nats-io/nats-server · error

'auth_callout' cannot be configured in FIPS-140 mode

Error message

'auth_callout' cannot be configured in FIPS-140 mode

What it means

When parsing server options (config file), an 'auth_callout' or 'auth_hook' block is rejected if FIPS-140 mode is enabled (fips140.Enabled()). Auth callout relies on crypto not approved for FIPS-140, so the combination is explicitly disallowed and the server reports this error during option parsing.

Source

Thrown at server/opts.go:4624

			auth.timeout = at
		case "users":
			nkeys, users, err := parseUsers(tk, errors)
			if err != nil {
				*errors = append(*errors, err)
				continue
			}
			auth.users = users
			auth.nkeys = nkeys
		case "default_permission", "default_permissions", "permissions":
			permissions, err := parseUserPermissions(tk, errors)
			if err != nil {
				*errors = append(*errors, err)
				continue
			}
			auth.defaultPermissions = permissions
		case "auth_callout", "auth_hook":
			if fips140.Enabled() {
				*errors = append(*errors, fmt.Errorf("'auth_callout' cannot be configured in FIPS-140 mode"))
				continue
			}
			ac, err := parseAuthCallout(tk, errors)
			if err != nil {
				*errors = append(*errors, err)
				continue
			}
			auth.callout = ac
		case "proxy_required":
			auth.proxyRequired = mv.(bool)
		default:
			if !tk.IsUsedVariable() {
				err := &unknownConfigFieldErr{
					field: mk,
					configErr: configErr{
						token: tk,
					},
				}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Remove the auth_callout/auth_hook block from the config, or disable FIPS-140 mode — the two cannot coexist
  2. Replace auth callout with NKeys/JWT-based (decentralized) authentication compatible with FIPS mode
  3. Use an external auth proxy instead of auth_callout in FIPS deployments
  4. Check fips140.Enabled() settings (build/env) to confirm why FIPS mode is active

Example fix

// before (config)
fips_140: true
auth_callout {
  issuer: "..."
  auth_users: ["svc"]
}
// after
fips_140: true
# auth_callout removed; use accounts/NKeys instead
Defensive patterns

Strategy: validation

Validate before calling

if fips140.Enabled() {
	if hasAuthCallout(cfg) {
		log.Fatal("auth_callout is not allowed in FIPS-140 mode")
	}
}

Type guard

func authCalloutAllowed(fips bool, cfg map[string]any) bool {
	_, hasCallout := cfg["auth_callout"]
	return !(fips && hasCallout)
}

Try / catch

if err := server.ProcessConfigFile(path); err != nil {
	if strings.Contains(err.Error(), "FIPS") {
		log.Fatal("remove auth_callout or disable FIPS-140 mode")
	}
}

Prevention

When it happens

Trigger: Starting nats-server with both a FIPS-140 configuration (e.g. fips_140: true / GODELIBRYPTO-style mode) and an 'auth_callout' (or legacy 'auth_hook') block in the server config.

Common situations: Enabling FIPS mode for compliance while an existing config still contains an auth_callout section; migrating a config with auth_callout onto FIPS-hardened deployments; operator unaware auth_callout is unsupported under FIPS-140.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/7065eed020b92360. Report an issue: GitHub.