apache/pulsar · error · RuntimeException

Access to environment variable %s is not allowed.

Error message

Access to environment variable %s is not allowed.

What it means

getUserConfigValue treats any string config value starting with '$' as an environment-variable reference and substitutes System.getenv(). If the JVM's SecurityManager denies reading that environment variable, a SecurityException is caught and rethrown as a RuntimeException stating access to the environment variable is not allowed.

Source

Thrown at pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ContextImpl.java:347

    }

    @Override
    public Logger getLogger() {
        return logger;
    }

    @Override
    public Optional<Object> getUserConfigValue(String key) {
        Object value = userConfigs.getOrDefault(key, null);

        if (value instanceof String && ((String) value).startsWith("$")) {
            // any string starts with '$' is considered as system env symbol and will be
            // replaced with the actual env value
            try {
                String actualValue = System.getenv(((String) value).substring(1));
                return Optional.ofNullable(actualValue);
            } catch (SecurityException ex) {
                throw new RuntimeException("Access to environment variable " + value + " is not allowed.", ex);
            }
        } else {
            return Optional.ofNullable(value);
        }
    }

    @Override
    public Object getUserConfigValueOrDefault(String key, Object defaultValue) {
        return getUserConfigValue(key).orElse(defaultValue);
    }

    @Override
    public Map<String, Object> getUserConfigMap() {
        return userConfigs;
    }

    @Override
    public String getSecret(String secretName) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Remove or change the '$' prefix in the user config if the value is meant to be a literal string (escape/double it per docs if needed).
  2. Set the referenced environment variable in the function's runtime environment so it exists and is readable.
  3. Relax the function worker's security policy / JVM permissions to allow System.getenv for that variable.

Example fix

// before
String secret = (String) context.getUserConfigValue("secret"); // value in config: "$SECRET_TOKEN"
// after
// change config value to the literal or inject the env var into the function pod,
// then:
String secret = (String) context.getUserConfigValueOrDefault("secret", "default");
Defensive patterns

Strategy: validation

Validate before calling

Object v = context.getUserConfig("key");
if (v instanceof String s && s.startsWith("$") && System.getenv(s.substring(1)) == null) {
    throw new IllegalStateException("Env var " + s.substring(1) + " not resolvable for config key");
}

Try / catch

try { return context.getUserConfigValue("key"); } catch (RuntimeException e) { if (e.getMessage().contains("Access to environment variable")) { return Optional.of(defaultValue); } throw e; }

Prevention

When it happens

Trigger: A user config value looks like "$MY_VAR" (single $ prefix), the function worker's security policy (Java SecurityManager) blocks System.getenv for that name, and the function calls context.getUserConfigValue("key") (directly or via getUserConfigValueOrDefault).

Common situations: Config values that accidentally start with '$' (e.g. "$password", shell-style literals pasted into config); hardened function-worker policies restricting env access; running functions inside containers with restricted JVM permissions.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/d2eb75b59ca0029d. Report an issue: GitHub.