apache/pulsar · error · IllegalArgumentException
Couldn't get the access key id.
Error message
Couldn't get the access key id.
What it means
Thrown by the Aliyun OSS credential builder when no access key id can be found in the environment. It first checks ACCESS_KEY_ID, then falls back to the legacy ALIYUN_OSS_ACCESS_KEY_ID for forward compatibility; if both are empty/whitespace, the provider cannot authenticate to OSS and throws IllegalArgumentException.
Source
Thrown at tiered-storage/jcloud/src/main/java/org/apache/bookkeeper/mledger/offload/jcloud/provider/JCloudBlobStoreProvider.java:461
String configId = config.getConfigProperty(S3_ID_FIELD);
String configSecret = config.getConfigProperty(S3_SECRET_FIELD);
if (StringUtils.isNotBlank(configId) || StringUtils.isNotBlank(configSecret)) {
if (StringUtils.isBlank(configId) || StringUtils.isBlank(configSecret)) {
throw new IllegalArgumentException(
"Both " + S3_ID_FIELD + " and " + S3_SECRET_FIELD
+ " must be set when providing offload credentials in the configuration");
}
Credentials credentials = new Credentials(configId, configSecret);
config.setProviderCredentials(() -> credentials);
return;
}
String accountName = System.getenv().getOrDefault("ACCESS_KEY_ID", "");
// For forward compatibility
if (StringUtils.isEmpty(accountName.trim())) {
accountName = System.getenv().getOrDefault("ALIYUN_OSS_ACCESS_KEY_ID", "");
}
if (StringUtils.isEmpty(accountName.trim())) {
throw new IllegalArgumentException("Couldn't get the access key id.");
}
String accountKey = System.getenv().getOrDefault("ACCESS_KEY_SECRET", "");
if (StringUtils.isEmpty(accountKey.trim())) {
accountKey = System.getenv().getOrDefault("ALIYUN_OSS_ACCESS_KEY_SECRET", "");
}
if (StringUtils.isEmpty(accountKey.trim())) {
throw new IllegalArgumentException("Couldn't get the access key secret.");
}
Credentials credentials = new Credentials(
accountName, accountKey);
config.setProviderCredentials(() -> credentials);
};
}
View on GitHub (pinned to 820761864e)
Solutions
- Export ACCESS_KEY_ID (or ALIYUN_OSS_ACCESS_KEY_ID) in the broker process environment before startup.
- In containers/K8s, add the env var to the deployment/envFile so it reaches the JVM.
- Alternatively supply credentials via the S3-prefixed config properties (both id and secret) so the env path isn't needed.
- Restart the broker after setting the variable — env vars are read at credential-build time, not dynamically.
Example fix
# before: no env vars # after export ACCESS_KEY_ID=LTAI... export ACCESS_KEY_SECRET=... # then restart the broker
Defensive patterns
Strategy: validation
Validate before calling
String id = System.getenv("ACCESS_KEY_ID");
if (id == null || id.trim().isEmpty()) {
id = System.getenv("ALIYUN_OSS_ACCESS_KEY_ID");
}
if (id == null || id.trim().isEmpty()) {
throw new IllegalStateException("OSS offload requires ACCESS_KEY_ID (or ALIYUN_OSS_ACCESS_KEY_ID) in the environment");
} Try / catch
try {
provider.validateConfig(cfg);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Couldn't get the access key id")) {
log.error("OSS access key id missing from environment; set ACCESS_KEY_ID and restart", e);
}
} Prevention
- Set credentials in the broker's startup environment (systemd EnvironmentFile, K8s env, docker --env-file).
- Verify with `sudo -u pulsar env | grep ACCESS_KEY` that the broker process actually sees the variables.
- Restart the broker after changing environment variables.
- Remember the OSS builder reads env, not config properties.
When it happens
Trigger: Using the aliyun-oss (OSS) offload driver without either ACCESS_KEY_ID or ALIYUN_OSS_ACCESS_KEY_ID set in the broker's process environment, or the variable set only to whitespace.
Common situations: Broker started by systemd/container that doesn't pass the env var through; credentials configured in config properties instead but using the S3 keys, which the OSS builder ignores; renamed variables after migration; missing env_file in docker-compose/K8s manifest.
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
- Couldn't get the access key secret.
- Timeout during mark-delete operation
- Timeout during clear backlog operation
- Timeout during skip messages operation
- Both ${S3_ID_FIELD} and ${S3_SECRET_FIELD} must be set when
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/665c090ed5a35765.
Report an issue: GitHub.