RocketChat/Rocket.Chat · warning

WARNING: Push APN is in development mode

Error message

WARNING: Push APN is in development mode

What it means

During push initialization, the explicitly configured options.apn.gateway equals 'gateway.sandbox.push.apple.com', so iOS notifications are routed through Apple's sandbox environment. Sandbox pushes only deliver to development-signed app builds; App Store/production builds will silently receive nothing.

Source

Thrown at apps/meteor/server/lib/notifications/push/apn.ts:132

	}
};

export const initAPN = ({ options, absoluteUrl }: { options: RequiredField<PushOptions, 'apn'>; absoluteUrl: string }) => {
	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');

View on GitHub (pinned to b2c16d5842)

Solutions

  1. No action needed if you are intentionally testing a development build — verify the app is also dev-signed or pushes will not arrive
  2. For production, remove the gateway override (or point it at 'gateway.push.apple.com') and use a production push certificate/token
  3. Make sure cert/key match the environment: sandbox cert + sandbox gateway, prod cert + prod gateway
  4. Remove the explicit gateway option entirely and let the APN client infer the environment from the credentials

Example fix

// before
push: { apn: { gateway: 'gateway.sandbox.push.apple.com', ... } }

// after (production)
push: { production: true, apn: { ... } } // no gateway override
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_APN_GATEWAYS = ['gateway.sandbox.push.apple.com', 'gateway.push.apple.com'];

if (options.apn.gateway === 'gateway.sandbox.push.apple.com' && process.env.NODE_ENV === 'production') {
  throw new Error('Refusing to start with sandbox APN gateway in production');
}

Prevention

When it happens

Trigger: Rocket.Chat push is configured with the sandbox APN gateway — normally deliberate, while testing push with a development iOS build and development push certificate.

Common situations: Mobile dev testing with Xcode builds; sandbox credentials left in place when promoting to production; copying a dev push config template wholesale.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/216dd0256060a25c. Report an issue: GitHub.