{"record":{"id":"52ceea153a7f990b","repo":"apache/iceberg","slug":"invalid-idempotency-lifetime","errorCode":null,"errorMessage":"Invalid idempotency lifetime: ","messagePattern":"Invalid idempotency lifetime: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/rest/CatalogHandlers.java","lineNumber":208,"sourceCode":"    try {\n      T res = action.get();\n      entry.finalizeSuccess(res);\n      return res;\n    } catch (RuntimeException e) {\n      entry.finalizeError(e);\n      throw e;\n    }\n  }\n\n  @VisibleForTesting\n  static void setIdempotencyLifetimeFromIso(String isoDuration) {\n    if (isoDuration == null) {\n      return;\n    }\n    try {\n      idempotencyLifetimeMillis = Duration.parse(isoDuration).toMillis();\n    } catch (Exception e) {\n      throw new IllegalArgumentException(\"Invalid idempotency lifetime: \" + isoDuration, e);\n    }\n  }\n\n  private static final class IdempotencyEntry {\n    enum Status {\n      IN_PROGRESS,\n      FINALIZED\n    }\n\n    private final CountDownLatch latch;\n    private final long firstSeenMillis;\n    private volatile Status status;\n    private volatile Object responseBody;\n    private volatile RuntimeException error;\n\n    private IdempotencyEntry(Status status) {\n      this.status = status;\n      this.latch = new CountDownLatch(1);","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/rest/CatalogHandlers.java#L190-L226","documentation":"The REST catalog server failed to parse the idempotency lifetime configuration value into a Duration. setIdempotencyLifetimeFromIso expects an ISO-8601 duration string (e.g. PT30M); any unparseable value throws this IllegalArgumentException. The value comes from server config, so a bad setting breaks catalog handler configuration.","triggerScenarios":"Configuring the REST server's idempotency lifetime with a string that Duration.parse() cannot parse as ISO-8601 (e.g. '30m', '3600', '1 hour'); null is allowed and skips the setting.","commonSituations":"Deployment config mistakes using plain time strings or numbers instead of ISO-8601 duration format; typos such as missing the 'PT' prefix.","solutions":["Use ISO-8601 duration syntax: PT prefix, e.g. PT30S, PT10M, PT1H","Remove the property to use the default lifetime","Validate the config with Duration.parse in a startup check","Check startup logs for the exact offending value and fix the config"],"exampleFix":"// before\nrest.idempotency.lifetime=30m\n// after\nrest.idempotency.lifetime=PT30M","handlingStrategy":"validation","validationCode":"String v = config.get(\"rest.idempotency.lifetime\");\nif (v != null) {\n  try {\n    java.time.Duration.parse(v);\n  } catch (DateTimeParseException e) {\n    throw new IllegalArgumentException(\"Not an ISO-8601 duration: \" + v);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  startServer(config);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Invalid idempotency lifetime\")) {\n    // fix config and restart\n  }\n}","preventionTips":["Always use PT-prefixed ISO-8601 durations in REST server config","Lint duration config values at deploy time","Test server startup with the full config before deploying"],"tags":["rest-catalog","configuration","iso-8601","duration"],"backgroundTag":"invalid-duration-format","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}