ios#7 asks for verification on two physical devices, which is the only
way to exercise push, VoIP push and the microphone. That part cannot be
done from here. What can be done is removing the reason it is dangerous.
The relay defaults to the APNs SANDBOX host. A TestFlight or App Store
build mints tokens only the production host understands. Ship without
setting FN_APNS_ENV=production and every push is refused, no iPhone
ever rings, and the log says:
APNs refused a push: 400 {"reason":"BadDeviceToken"}
which reads as a bad token. It is not a bad token; it is the one setting
nobody remembered. A total, silent failure of the feature people notice
first, presented as somebody else's problem.
Now it says:
APNs refused a push: 400 BadDeviceToken. This relay is sending to the
sandbox host, so this is almost certainly a token from a production
build — set FN_APNS_ENV=production and restart. Until then no push
from this relay will arrive.
"Almost certainly", never "is". APNs returns the same reason whichever
way round the mismatch is, and a genuinely malformed token produces it
too — a diagnosis stated as fact would send somebody to change a
configuration that was right. Every other refusal is passed through
untouched, so an unrelated failure does not acquire an environment
theory.
Two more things it was hiding:
The VoIP branch threw the reason away entirely and logged only
"failed: 400" — the path where this matters most, because a call
that never rings is what gets noticed first.
Startup logged the environment at notice, one line among a hundred.
Sandbox is the DEFAULT and production is the deliberate state, so
sandbox now warns, saying plainly that no TestFlight build can
receive anything.
670 tests on macOS, and a clean Linux build in swift:6.1-noble.
ios#7 asks for verification on two physical devices, which is the only
way to exercise push, VoIP push and the microphone. That part cannot be
done from here. What can be done is removing the reason it is dangerous.
The relay defaults to the APNs SANDBOX host. A TestFlight or App Store
build mints tokens only the production host understands. Ship without
setting `FN_APNS_ENV=production` and every push is refused, no iPhone
ever rings, and the log says:
APNs refused a push: 400 {"reason":"BadDeviceToken"}
which reads as a bad token. It is not a bad token; it is the one setting
nobody remembered. A total, silent failure of the feature people notice
first, presented as somebody else's problem.
Now it says:
APNs refused a push: 400 BadDeviceToken. This relay is sending to the
sandbox host, so this is almost certainly a token from a production
build — set FN_APNS_ENV=production and restart. Until then no push
from this relay will arrive.
"Almost certainly", never "is". APNs returns the same reason whichever
way round the mismatch is, and a genuinely malformed token produces it
too — a diagnosis stated as fact would send somebody to change a
configuration that was right. Every other refusal is passed through
untouched, so an unrelated failure does not acquire an environment
theory.
Two more things it was hiding:
- The VoIP branch threw the reason away entirely and logged only
"failed: 400" — the path where this matters most, because a call
that never rings is what gets noticed first.
- Startup logged the environment at `notice`, one line among a hundred.
Sandbox is the DEFAULT and production is the deliberate state, so
sandbox now warns, saying plainly that no TestFlight build can
receive anything.
670 tests on macOS, and a clean Linux build in `swift:6.1-noble`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
ios#7 asks for verification on two physical devices, which is the only
way to exercise push, VoIP push and the microphone. That part cannot be
done from here. What can be done is removing the reason it is dangerous.
The relay defaults to the APNs SANDBOX host. A TestFlight or App Store
build mints tokens only the production host understands. Ship without
setting
FN_APNS_ENV=productionand every push is refused, no iPhoneever rings, and the log says:
which reads as a bad token. It is not a bad token; it is the one setting
nobody remembered. A total, silent failure of the feature people notice
first, presented as somebody else's problem.
Now it says:
"Almost certainly", never "is". APNs returns the same reason whichever
way round the mismatch is, and a genuinely malformed token produces it
too — a diagnosis stated as fact would send somebody to change a
configuration that was right. Every other refusal is passed through
untouched, so an unrelated failure does not acquire an environment
theory.
Two more things it was hiding:
"failed: 400" — the path where this matters most, because a call
that never rings is what gets noticed first.
notice, one line among a hundred.Sandbox is the DEFAULT and production is the deliberate state, so
sandbox now warns, saying plainly that no TestFlight build can
receive anything.
670 tests on macOS, and a clean Linux build in
swift:6.1-noble.Co-Authored-By: Claude Opus 5 noreply@anthropic.com
assigned to @paulhitt
mentioned in commit
d3723202f1changed the description