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

  1. Remove extra colons — supply only client-id:client-secret or client-secret alone
  2. URL-encode colons inside the client secret (e.g. %3A) if the provider requires them
  3. Generate a fresh credential without special characters if the provider allows
  4. 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

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


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)