{"record":{"id":"10df4c71240c9a99","repo":"apache/seatunnel","slug":"retry-backoff-max-ms-must-be-effective-retry-ba","errorCode":null,"errorMessage":"retry.backoff-max-ms must be >= effective retry.backoff-ms (${backoffMs} ms).","messagePattern":"retry\\.backoff-max-ms must be >= effective retry\\.backoff-ms \\((.+?) ms\\)\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-edge-agent/seatunnel-edge-agent-starter/src/main/java/org/apache/seatunnel/edge/agent/starter/config/RetryConfig.java","lineNumber":51,"sourceCode":"    private final int maxAttempts;\n    private final long backoffMs;\n    private final long backoffMaxMs;\n\n    public RetryConfig(ReadonlyConfig config) {\n        Objects.requireNonNull(config, \"config\");\n        ConfigValidator.of(config).validate(EdgeAgentRuntimeOptionRules.retryRule());\n\n        this.maxAttempts = config.get(EdgeAgentRuntimeOptions.RETRY_MAX_ATTEMPTS);\n        if (this.maxAttempts < 1) {\n            throw new IllegalArgumentException(\"retry.max-attempts must be >= 1.\");\n        }\n        this.backoffMs = config.get(EdgeAgentRuntimeOptions.RETRY_BACKOFF_MS);\n        if (this.backoffMs < 0L) {\n            throw new IllegalArgumentException(\"retry.backoff-ms must be >= 0.\");\n        }\n        this.backoffMaxMs = config.get(EdgeAgentRuntimeOptions.RETRY_BACKOFF_MAX_MS);\n        if (this.backoffMaxMs < this.backoffMs) {\n            throw new IllegalArgumentException(\n                    \"retry.backoff-max-ms must be >= effective retry.backoff-ms (\"\n                            + this.backoffMs\n                            + \" ms).\");\n        }\n    }\n\n    public static RetryConfig from(ReadonlyConfig config) {\n        return new RetryConfig(config);\n    }\n}\n","sourceCodeStart":33,"sourceCodeEnd":62,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-edge-agent/seatunnel-edge-agent-starter/src/main/java/org/apache/seatunnel/edge/agent/starter/config/RetryConfig.java#L33-L62","documentation":"RetryConfig enforces that retry.backoff-max-ms (the cap for exponential backoff) is at least the effective retry.backoff-ms (the base delay). Otherwise backoff would start above its own ceiling, so the constructor throws IllegalArgumentException including the effective base delay.","triggerScenarios":"Constructing RetryConfig where RETRY_BACKOFF_MAX_MS < RETRY_BACKOFF_MS (after defaults are applied).","commonSituations":"User raises backoff-ms but forgets to raise backoff-max-ms; explicitly setting a small max while a large default base applies; partial copy-paste of retry config.","solutions":["Set retry.backoff-max-ms >= retry.backoff-ms.","Recheck both values after any change, since defaults affect the effective base.","Remove backoff-max-ms to let it default above the base if unsure."],"exampleFix":"# before\nretry:\n  backoff-ms: 5000\n  backoff-max-ms: 1000\n# after\nretry:\n  backoff-ms: 5000\n  backoff-max-ms: 60000","handlingStrategy":"validation","validationCode":"long backoffMs = config.get(EdgeAgentRuntimeOptions.RETRY_BACKOFF_MS);\nlong backoffMaxMs = config.get(EdgeAgentRuntimeOptions.RETRY_BACKOFF_MAX_MS);\nif (backoffMaxMs < backoffMs) {\n    throw new IllegalArgumentException(\"backoff-max-ms must be >= backoff-ms\");\n}","typeGuard":null,"tryCatchPattern":"try { RetryConfig retry = new RetryConfig(config); } catch (IllegalArgumentException e) { log.error(\"Retry config invalid: {}\", e.getMessage()); }","preventionTips":["When raising backoff-ms, raise backoff-max-ms proportionally.","Remember defaults count: compare against the effective base delay.","Keep max >= base * expected multiplier in generated configs."],"tags":["config","retry","validation"],"backgroundTag":"conflicting-config-options","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}