MeshService::run | error: {"stack":"ExpiredToken: The provided token has expired.
RCA: MeshService::run | ExpiredToken: The provided token has expired
Overview#
What Happened#
2026-05-22 19:11:15 KST, cupixworks-any-mesh-agent 서비스에서 BIM mesh 추출 후 S3 업로드 중 AWS STS 임시 토큰이 만료되어 ExpiredToken 에러가 발생했다. BIM ID 18044의 mesh archive 업로드가 약 4시간 동안 진행되면서 Tesla API에서 발급받은 임시 자격증명의 유효기간을 초과했다.
Quick Facts#
| Field | Value |
|---|---|
| exception.class | ExpiredToken |
| exception.message | The provided token has expired. |
| top_frame | aws-sdk/lib/services/s3.js:712 |
| runtime | Node.js (aws-sdk@2.1599.0) |
| env | production, us-west-2 |
Timeline#
- 2026-05-22 14:53:58 KST — SQS 메시지 수신 (BIM id: 18044)
- 2026-05-22 15:10:17 KST — S3 업로드 시작 (mesh archive:
/tmp/workspace/18044/mesh_archive/18044.zip) - 2026-05-22 19:11:15 KST — S3 업로드 실패 (
ExpiredToken, 약 4시간 경과) - 2026-05-22 19:11:16 KST — 워크스페이스 정리 및 SQS 메시지 삭제
Error Log#
MeshService::run | error: {"stack":"ExpiredToken: The provided token has expired.
at Request.extractError (/tmp/agent/dist/node_modules/.pnpm/aws-sdk@2.1599.0/node_modules/aws-sdk/lib/services/s3.js:712:35)
at Request.callListeners (/tmp/agent/dist/node_modules/.pnpm/aws-sdk@2.1599.0/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/tmp/agent/dist/node_modules/.pnpm/aws-sdk@2.1599.0/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/tmp/agent/dist/node_modules/.pnpm/aws-sdk@2.1599.0/node_modules/aws-sdk/lib/request.js:686:14)
at Request.transition (/tmp/agent/dist/node_modules/.pnpm/aws-sdk@2.1599.0/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/tmp/agent/dist/node_modules/.pnpm/aws-sdk@2.1599.0/node_modules/aws-sdk/lib/state_machine.js:14:12)","message":"The provided token has expired.","code":"ExpiredToken","region":null,"name":"ExpiredToken","time":"2026-05-22T10:11:15.962Z","requestId":"8H25DQC71K6CFB0D","extendedRequestId":"v5zjP4f/7bIwXWtfZhBrKiZ/rvlh16PRNAQGM+FvQxLZU/BJtqAVK8DEaLKgdv2ZGPhaIVVig6I=","statusCode":400,"retryable":true}
Impact#
- Service:
cupixworks-any-mesh-agent - Team: gad
- 발생 횟수: 1
- 최초 발생: 2026-05-22T10:11:15.967Z
- 최근 발생: 2026-05-22T10:11:15.967Z
Root Cause Summary#
Tesla API에서 발급받은 STS 임시 자격증명(session token)으로 S3 업로드를 시작했으나, mesh archive 파일 크기가 매우 커서 업로드에 약 4시간이 소요되었다. AwsS3Manager에는 토큰 만료 시 자동 갱신하는 checkToken 메커니즘이 존재하지만, MeshService에서 setApiCreateCredentials를 호출하지 않아 _createCredentials가 undefined로 남아 있어 토큰 갱신이 불가능했다. 또한 checkToken은 업로드 시작 전에만 1회 호출되므로, 업로드 도중 토큰이 만료되는 경우를 처리할 수 없다.
Technical Analysis#
Code Path#
- Entry point:
mesh-service.ts:101—MeshService.run(targetId) - 1단계: Forge 인증 + mesh 추출 + archive 생성 (14:53 ~ 15:10, 약 17분)
- 2단계:
uploadMeshArchiveFileByCPBim→uploadBimMeshArchiveFile호출 - Failure point:
aws-s3.manager.ts:98-111—s3.upload()콜백에서ExpiredToken에러 수신
private uploadBimMeshArchiveFile = async (cpBim: CPBim): Promise<void> => {
if (cpBim.meshArchiveFilePath === undefined) {
throw new Error('MeshService::uploadBimMeshArchiveFile - not found mesh');
}
this.awsS3Manager.resetS3Info(); // _createCredentials = undefined로 초기화
const s3Credentials = await this.createMeshResourceCredentials(cpBim);
// ... credential 검증 ...
this.awsS3Manager.setCredentials({
accessKeyId: s3Credentials.aws_access_key_id,
secretAccessKey: s3Credentials.aws_secret_access_key,
sessionToken: s3Credentials.aws_session_token,
expires_at: s3Credentials.expires_at,
endpoint: s3Credentials.endpoint
});
await this.awsS3Manager.uploadFileStreamToS3({
bucketName: s3Credentials.bucket_name,
bucketKeyPath: s3Credentials.basepath,
targetFilePath: cpBim.meshArchiveFilePath,
acl: s3Credentials.acl
});
};
resetS3Info() 호출로 _createCredentials가 undefined가 되며, 이후 setApiCreateCredentials를 호출하지 않으므로 토큰 갱신 경로가 비활성화된다.
private checkToken = async () => {
let isExpired = false;
if (this.tokenExpiresAt != undefined) {
const now = new Date().getTime();
const expiresTimeStamp = new Date(this.tokenExpiresAt).getTime();
isExpired = expiresTimeStamp - 600 * 1000 < now;
}
if (!isExpired || this._createCredentials == undefined) {
return; // _createCredentials가 undefined이므로 만료되어도 갱신 불가
}
const _credentials = await this._createCredentials();
this.setCredentials({
accessKeyId: _credentials.aws_access_key_id,
secretAccessKey: _credentials.aws_secret_access_key,
sessionToken: _credentials.aws_session_token,
expires_at: _credentials.expires_at,
endpoint: _credentials.endpoint
});
};
checkToken은 uploadFileStreamToS3 시작 시 1회만 호출된다(aws-s3.manager.ts:91). 업로드 스트림이 진행되는 동안에는 토큰 상태를 확인하지 않으며, AWS SDK v2의 s3.upload()는 내부적으로 multipart upload를 수행하지만 자격증명 갱신 콜백을 지원하지 않는다.
Log Evidence#
사용한 Datadog 쿼리:
service:cupixworks-any-mesh-agent "18044"
타임라인 로그:
2026-05-22 14:53:58 KST | info | BaseService::runByMessage | id: 18044
2026-05-22 15:10:17 KST | info | AwsS3Manager::uploadFileStreamToS3 | begin - filePath: /tmp/workspace/18044/mesh_archive/18044.zip, bucketPath: cupixworks-source-b169da1a0187-mece1/resources/zyn5iw/mece1/v15
2026-05-22 19:11:15 KST | error | AwsS3Manager::uploadFileStreamToS3 | failed: resources/zyn5iw/mece1/v15 - {"message":"The provided token has expired.","code":"ExpiredToken",...}
2026-05-22 19:11:15 KST | error | MeshService::run | error: {"stack":"ExpiredToken: The provided token has expired....",...,"retryable":true}
2026-05-22 19:11:16 KST | info | BaseService::cleanUpAnythingRelatedModel | path: /tmp/workspace/18044
업로드 시작(15:10:17)부터 실패(19:11:15)까지 약 3시간 58분 소요. AWS STS 세션 토큰의 기본 유효기간은 1시간(최대 12시간 설정 가능)이므로, 토큰이 업로드 중간에 만료됨.
service:cupixworks-any-mesh-agent "setCredentials"
같은 시간대에 setCredentials가 실패한 작업에 대해 호출된 기록이 없음 — 토큰 갱신 시도 자체가 발생하지 않았음을 확인.
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | STS 토큰 유효기간 초과 (대용량 파일 업로드 시간 > 토큰 TTL) | 업로드 시작~실패 간 4시간 경과 (로그 타임스탬프). checkToken에 _createCredentials가 미설정. AWS 응답 statusCode:400, retryable:true |
— | Confirmed |
| H2 | Tesla API의 credential 발급 자체가 만료된 토큰을 반환 | — | 업로드 시작 시점(15:10)에는 정상 동작했을 것 (즉시 실패했다면 더 빠른 에러 발생). 같은 시간대 다른 작업들은 정상 업로드 완료됨 (18:05~18:27) | Rejected |
| H3 | 네트워크 이슈로 업로드 지연 후 토큰 만료 | 4시간 소요는 비정상적으로 길며 네트워크 문제일 가능성 있음 | 파일이 대용량 mesh archive일 수 있음. 별도의 네트워크 에러 로그 없음 (순수 ExpiredToken만 발생) | Inconclusive |
Fix Recommendation#
즉시 조치 (Critical)#
packages/cupix-tesla-mesh-agent/src/mesh-service.ts:259—resetS3Info()호출 후setApiCreateCredentials를 등록하여 업로드 중 토큰 갱신이 가능하도록 수정uploadBimMeshArchiveFile메서드에서 credential 팩토리 함수를AwsS3Manager에 등록:typescriptthis.awsS3Manager.setApiCreateCredentials(() => this.cupixApi.bim.createResourceUploadCredentials(cpBim.id, 'mesh'));
단기 개선 (1주 이내)#
AwsS3Manager.uploadFileStreamToS3에서 S3 multipart upload 사용 시 각 파트 업로드 전checkToken호출하도록 개선. 현재는 업로드 시작 전 1회만 호출됨- 대용량 파일 업로드 시 AWS SDK v3의
@aws-sdk/lib-storage패키지 활용을 검토 — 내장 credential refresh 지원
장기 개선 (재발 방지)#
- AWS SDK v2에서 v3로 마이그레이션 (v2는 2025-09-08 EOL). SDK v3의 credential provider chain은 자동 갱신 지원
- 업로드 전 파일 크기 기반으로 예상 소요 시간을 계산하고, 토큰 유효기간보다 길면 multipart upload with credential refresh 전략을 자동 선택하는 로직 추가
Monitoring#
- 추가할 메트릭: S3 업로드 소요 시간 추적 (시작~완료 간 duration)
- Datadog 알림 쿼리:
service:cupixworks-any-mesh-agent "ExpiredToken"
service:cupixworks-any-mesh-agent "uploadFileStreamToS3 | failed"
- STS 토큰 만료까지 남은 시간이 10분 미만인 상태에서 업로드를 시작하는 경우 warn 로그 추가 권장
Risk Assessment#
- Risk level: low
- 예상 복잡도: standard
- 1건 발생이며 대용량 BIM mesh에서만 재현 가능. 같은 시간대 다른 작업은 정상 완료됨. 그러나 수정 없이는 대용량 모델에서 반복 발생 가능.