{"record":{"id":"9af3798404980bd5","repo":"apache/iceberg","slug":"failed-to-refresh-storage-credentials","errorCode":null,"errorMessage":"Failed to refresh storage credentials","messagePattern":"Failed to refresh storage credentials","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"aws/src/main/java/org/apache/iceberg/aws/s3/S3FileIO.java","lineNumber":476,"sourceCode":"\n  private void refreshStorageCredentials() {\n    if (isResourceClosed.get()) {\n      return;\n    }\n\n    try (VendedCredentialsProvider provider = VendedCredentialsProvider.create(properties)) {\n      List<StorageCredential> refreshed =\n          provider.fetchCredentials().credentials().stream()\n              .filter(c -> c.prefix().startsWith(ROOT_PREFIX))\n              .map(c -> StorageCredential.create(c.prefix(), c.config()))\n              .collect(Collectors.toList());\n\n      if (!refreshed.isEmpty() && !isResourceClosed.get()) {\n        this.storageCredentials = Lists.newArrayList(refreshed);\n        scheduleCredentialRefresh();\n      }\n    } catch (Exception e) {\n      LOG.warn(\"Failed to refresh storage credentials\", e);\n    }\n  }\n\n  private ScheduledExecutorService executorService() {\n    if (executorService == null) {\n      synchronized (S3FileIO.class) {\n        if (executorService == null) {\n          executorService =\n              ThreadPools.newExitingScheduledPool(\n                  \"iceberg-s3fileio-tasks\",\n                  clientForStoragePath(ROOT_PREFIX).s3FileIOProperties().deleteThreads(),\n                  Duration.ofSeconds(10));\n        }\n      }\n    }\n\n    return executorService;\n  }","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/aws/src/main/java/org/apache/iceberg/aws/s3/S3FileIO.java#L458-L494","documentation":"S3FileIO can refresh storage credentials periodically (e.g. when initialized with credential providers that rotate). refreshStorageCredentials() catches any exception during the refresh and logs this warning, keeping the previously loaded credentials in place. If refresh keeps failing, the stored credentials may eventually expire and requests will start failing with auth errors.","triggerScenarios":"Scheduled credential refresh runs while the credential provider cannot fetch new credentials (network failure, revoked AssumeRole, catalog unreachable, expired refresh token).","commonSituations":"IAM role trust policy changed; catalog/STS temporarily unavailable; clock skew invalidating SigV4 signatures; credentials configured statically so refresh always fails.","solutions":["Check the attached exception to find why the provider failed (auth vs network vs config)","Verify the AWS credentials chain and role trust policies are still valid","Ensure the catalog exposing credentials is reachable at refresh time","Correct clock skew on the client host if SigV4 signing errors appear"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// before initialize, verify the credential provider can resolve credentials\nAwsCredentials c = DefaultCredentialsProvider.create().resolveCredentials();","typeGuard":null,"tryCatchPattern":"try { io.initialize(props); } catch (RuntimeException e) { throw e; } // refresh failures are warnings; watch for later auth errors","preventionTips":["Keep role trust policies and STS permissions valid for the refresh identity","Monitor this warning rate — recurring refresh failures predict future auth failures","Ensure the credential-granting catalog is reachable from the compute environment"],"tags":["aws","credentials","iam","background-task"],"backgroundTag":"missing-credentials","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"}