apache/iceberg · error · IllegalArgumentException
Invalid credential:
Error message
Invalid credential:
What it means
Thrown by OAuth2Util.parseCredential when a credential string splits into more than 2 colon-separated parts. A valid credential is 'client-id:client-secret' or just 'client-secret'; anything with multiple extra colons is invalid.
Solutions
- Remove extra colons — supply only client-id:client-secret or client-secret alone
- URL-encode colons inside the client secret (e.g. %3A) if the provider requires them
- Generate a fresh credential without special characters if the provider allows
- Split correctly: the splitter is limited to 2 parts, so only one colon is allowed
Example fix
// before
conf.put("rest.credential", "client1:sec:ret");
// after
conf.put("rest.credential", "client1:sec%3Aret"); // or use a secret without colons Defensive patterns
Strategy: validation
Validate before calling
// validate credential format before configuring the catalog
String credential = "id:secret";
boolean valid = credential.indexOf(':') == credential.lastIndexOf(':');
if (!valid) throw new IllegalArgumentException("Credential must be 'client-id:client-secret' or 'client-secret'"); Type guard
boolean isValidCredential(String credential) {
return credential != null && credential.indexOf(':') == credential.lastIndexOf(':');
} Try / catch
try { Pair<String,String> p = OAuth2Util.parseCredential(credential); }
catch (IllegalArgumentException e) { /* fix credential format: at most one colon */ } Prevention
- URL-encode colons in secrets (%3A) when providers require them
- Validate credential format at config load time
- Never concatenate extra segments into the credential property
When it happens
Trigger: Passing a credential like 'id:secret:extra' (or an unescaped colon inside the secret) to OAuth2Util.credentialPair / client-credentials token exchange via catalog OAuth2 config.
Common situations: Secrets containing raw colons that were not URL-encoded; concatenating config values incorrectly; pasting credentials with trailing segments from a keyfile.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Failed to refresh token
- Not authorized
- Not authorized
- Cannot assume role to sign REST requests because is not…
- Cannot build StorageCredential, some of required attributes…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/18ae36cbeb93e065.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/rest/auth/OAuth2Util.java:302
}
formData.putAll(optionalParams);
return formData.buildKeepingLast();
}
private static Pair<String, String> parseCredential(String credential) {
Preconditions.checkNotNull(credential, "Invalid credential: null");
List<String> parts = CREDENTIAL_SPLITTER.splitToList(credential);
switch (parts.size()) {
case 2:
// client ID and client secret
return Pair.of(parts.get(0), parts.get(1));
case 1:
// client secret
return Pair.of(null, parts.get(0));
default:
// this should never happen because the credential splitter is limited to 2
throw new IllegalArgumentException("Invalid credential: " + credential);
}
}
private static Map<String, String> clientCredentialsRequest(
String credential, List<String> scopes, Map<String, String> optionalOAuthParams) {
Pair<String, String> credentialPair = parseCredential(credential);
return clientCredentialsRequest(
credentialPair.first(), credentialPair.second(), scopes, optionalOAuthParams);
}
private static Map<String, String> clientCredentialsRequest(
String clientId,
String clientSecret,
List<String> scopes,
Map<String, String> optionalOAuthParams) {
ImmutableMap.Builder<String, String> formData = ImmutableMap.builder();
formData.put(GRANT_TYPE, CLIENT_CREDENTIALS);
if (clientId != null) {View on GitHub (pinned to 86d9c8fc54)