apache/seatunnel · error · IllegalArgumentException
transport.aes-secret-key-base64 is required when transport.e
Error message
transport.aes-secret-key-base64 is required when transport.encryption is "aes_gcm".
What it means
EdgeTransportConfig validates the transport configuration at startup. When transport.encryption is set to "aes_gcm", packets are encrypted with AES-GCM, which requires a shared secret; the code reads transport.aes-secret-key-base64 and throws IllegalArgumentException if it is absent or blank. This fail-fast check prevents starting a transport that could not encrypt traffic.
Source
Thrown at seatunnel-edge-agent/seatunnel-edge-agent-transport/src/main/java/org/apache/seatunnel/edge/agent/transport/config/EdgeTransportConfig.java:71
this.endpoint = trimmedEndpoint;
String authType = config.get(EdgeTransportOptions.AUTH_TYPE);
validateAuthType(authType);
String rawToken = config.getOptional(EdgeTransportOptions.TOKEN).orElse(null);
if (rawToken == null || rawToken.trim().isEmpty()) {
throw new IllegalArgumentException("transport.token is required.");
}
this.token = rawToken.trim();
EdgePacketMode.from(config.get(EdgeTransportOptions.PACKET_MODE));
EdgePacketCompressionType.from(config.get(EdgeTransportOptions.COMPRESSION));
EdgePacketEncryptionType encryption =
EdgePacketEncryptionType.from(config.get(EdgeTransportOptions.ENCRYPTION));
if (encryption == EdgePacketEncryptionType.AES_GCM) {
String key =
config.getOptional(EdgeTransportOptions.AES_SECRET_KEY_BASE64).orElse(null);
if (key == null || key.trim().isEmpty()) {
throw new IllegalArgumentException(
"transport.aes-secret-key-base64 is required when transport.encryption"
+ " is \"aes_gcm\".");
}
}
this.connectTimeoutMs = config.get(EdgeTransportOptions.CONNECT_TIMEOUT_MS);
this.readTimeoutMs = config.get(EdgeTransportOptions.READ_TIMEOUT_MS);
this.maxBatchSendAttempts = config.get(EdgeTransportOptions.MAX_BATCH_SEND_ATTEMPTS);
this.initialBackoffMs = config.get(EdgeTransportOptions.INITIAL_BACKOFF_MS);
this.maxBackoffMs = config.get(EdgeTransportOptions.MAX_BACKOFF_MS);
this.maxReconnectCycles = config.get(EdgeTransportOptions.MAX_RECONNECT_CYCLES);
}
public static EdgeTransportConfig from(ReadonlyConfig config) {
return new EdgeTransportConfig(config);
}
public static long computeBackoffMillis(long attempt, long initial, long max) {View on GitHub (pinned to cf67b549a7)
Solutions
- Set transport.aes-secret-key-base64 in the agent config to a Base64-encoded 128/192/256-bit key (e.g. generate with `openssl rand -base64 32`).
- If encryption is not needed, change transport.encryption to "none" (or remove it) so the key is not required.
- If the key is injected via environment placeholder, verify the variable is actually set in the agent's runtime environment.
- Confirm there are no typos in the option name transport.aes-secret-key-base64 and that the key is in the config file actually loaded.
Example fix
// before
transport {
encryption = "aes_gcm"
}
// after
transport {
encryption = "aes_gcm"
aes-secret-key-base64 = "bXktMzItYnl0ZS1zZWNyZXQta2V5LTEyMzQ1Njc4"
} Defensive patterns
Strategy: validation
Validate before calling
Config cfg = ConfigProvider.getConfig();
String encryption = cfg.hasPath("transport.encryption") ? cfg.getString("transport.encryption") : "none";
if ("aes_gcm".equalsIgnoreCase(encryption)
&& (!cfg.hasPath("transport.aes-secret-key-base64")
|| cfg.getString("transport.aes-secret-key-base64").trim().isEmpty())) {
throw new IllegalStateException("transport.aes-secret-key-base64 must be set when transport.encryption=aes_gcm");
} Type guard
boolean hasAesKey(Config cfg) {
return !"aes_gcm".equalsIgnoreCase(cfg.getString("transport.encryption"))
|| cfg.hasPath("transport.aes-secret-key-base64")
&& !cfg.getString("transport.aes-secret-key-base64").trim().isEmpty();
} Try / catch
try {
EdgeTransportConfig transportConfig = new EdgeTransportConfig(config);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("aes-secret-key-base64")) {
LOG.error("Transport encryption requires a Base64 AES key; fix config and restart", e);
}
throw e;
} Prevention
- Generate and store the Base64 key once (openssl rand -base64 32) and reference it via a templated config.
- Keep encryption mode and key in the same config template so they are added/removed together.
- Run a config dry-run validation step in CI before deploying agent configs.
- Never hand-edit encryption mode without checking the dependent key options.
When it happens
Trigger: Constructing EdgeTransportConfig (from a Config) with EdgeTransportOptions.ENCRYPTION resolved to AES_GCM while config.getOptional(EdgeTransportOptions.AES_SECRET_KEY_BASE64) returns empty or a whitespace-only string.
Common situations: User sets transport.encryption = "aes_gcm" in the agent HOCON file but forgets the key entry; the key is supplied via an env var that is not exported; a copy-pasted key consisting of only spaces; upgrading from "none" encryption to "aes_gcm" without adding the new option.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Invalid secret_key: not Base64 encoded
- Unknown encryption: ${value}
- Schema config can not be empty
- Unknown format type:
- Option '${option}' cannot be blank
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/1b645dd68e9efaf9.
Report an issue: GitHub.