RocketChat/Rocket.Chat · warning
WARNING: Push APN is configured to production mode - but ser
Error message
WARNING: Push APN is configured to production mode - but server is running from localhost
What it means
The push APN init detected a contradiction: options.apn.gateway is the production Apple gateway, but the server's absolute URL is http://localhost*, i.e. a local development server sending through production APN. Production pushes require production credentials and a reachable server; this combo usually means leftover production push config on a dev box.
Source
Thrown at apps/meteor/server/lib/notifications/push/apn.ts:136
logger.debug('APN configured');
if (options.apn.gateway) {
// We check the apn gateway i the options, we could risk shipping
// server into production while using the production configuration.
// On the other hand we could be in development but using the production
// configuration. And finally we could have configured an unknown apn
// gateway (this could change in the future - but a warning about typos
// can save hours of debugging)
//
// Warn about gateway configurations - it's more a guide
if (options.apn.gateway === 'gateway.sandbox.push.apple.com') {
// Using the development sandbox
logger.warn('WARNING: Push APN is in development mode');
} else if (options.apn.gateway === 'gateway.push.apple.com') {
// In production - but warn if we are running on localhost
if (/http:\/\/localhost/.test(absoluteUrl)) {
logger.warn('WARNING: Push APN is configured to production mode - but server is running from localhost');
}
} else {
// Warn about gateways we dont know about
logger.warn({
msg: 'WARNING: Push APN unknown gateway',
gateway: options.apn.gateway,
});
}
} else if (options.production) {
if (/http:\/\/localhost/.test(absoluteUrl)) {
logger.warn('WARNING: Push APN is configured to production mode - but server is running from localhost');
}
} else {
logger.warn('WARNING: Push APN is in development mode');
}
// Check certificate data
if (!options.apn.cert?.length) {View on GitHub (pinned to b2c16d5842)
Solutions
- For local testing, switch to sandbox credentials and remove the production gateway
- If this server really is production-facing, set ROOT_URL to its public HTTPS URL so the check no longer matches localhost
- Keep per-environment config files so dev and prod push settings never mix
- Confirm the production push certificate/key are actually installed before relying on production sends
Example fix
// before
ROOT_URL='http://localhost:3000'
push: { apn: { gateway: 'gateway.push.apple.com' } }
// after
ROOT_URL='https://chat.example.com'
push: { apn: { gateway: 'gateway.push.apple.com' } } Defensive patterns
Strategy: validation
Validate before calling
const isLocalhostUrl = (url: string): boolean => /http:\/\/localhost/.test(url);
if (options.apn.gateway === 'gateway.push.apple.com' && isLocalhostUrl(absoluteUrl)) {
throw new Error('Production APN gateway with localhost ROOT_URL — fix ROOT_URL or use sandbox credentials');
} Prevention
- Set ROOT_URL to the public HTTPS URL on any server using production push config
- Never copy production push settings onto a local dev instance
- Keep environment-specific config templates to prevent env mixing
When it happens
Trigger: options.apn.gateway === 'gateway.push.apple.com' while ROOT_URL is http://localhost:PORT — e.g. testing push locally with the production push configuration copied from a live server.
Common situations: Developers cloning production settings to reproduce a push bug locally; docker-compose dev setups with production env vars; forgetting to switch ROOT_URL/gateway when moving configs between environments.
Related errors
- WARNING: Push APN is in development mode
- WARNING: Push APN unknown gateway
- error-push-disabled
- Livechat secret token is not configured
- Invalid MONGO_OPTIONS environment variable: must be valid JS
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/3c79c2114d71f1c4.
Report an issue: GitHub.