ES /docs

AwsS3Manager::uploadFileStreamToS3 | failed: resources/zyn5iw/mece1/v15 - {"message":"The provided t

RCA: AwsS3Manager::uploadFileStreamToS3 | ExpiredToken

Overview#

What Happened#

2026-05-22 cupixworks-any-mesh-agent 서비스에서 mesh archive 파일을 S3에 업로드하는 중 AWS STS 임시 토큰이 만료되어 업로드가 실패했다. 업로드 시작(15:10:17 KST)부터 실패(19:11:15 KST)까지 약 4시간이 소요되었으며, 이 시간 동안 토큰이 갱신되지 않았다.

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#

  1. 2026-05-22 15:10:17 KSTsetCredentials 호출 후 S3 업로드 시작 (workspace 18044, bucket path resources/zyn5iw/mece1/v15)
  2. 2026-05-22 19:11:15 KST — 약 4시간 후 ExpiredToken 에러로 업로드 실패
  3. 2026-05-22 19:11:16 KSTcleanUpAnythingRelatedModel 호출, SQS 메시지 삭제

Error Log#

Datadog Logs

text
AwsS3Manager::uploadFileStreamToS3 | failed: resources/zyn5iw/mece1/v15 - {"message":"The provided token has expired.","code":"ExpiredToken","region":null,"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.966Z
  • 최근 발생: 2026-05-22T10:11:15.966Z

BIM mesh 추출 완료 후 S3 업로드 실패로 인해 해당 BIM 모델의 mesh_stateerror로 전환된다. 사용자는 mesh 데이터를 사용할 수 없으며 재처리가 필요하다.

Root Cause Summary#

Mesh agent의 uploadBimMeshArchiveFile 메서드에서 setApiCreateCredentials를 호출하지 않아 AwsS3Manager.checkToken()의 자동 토큰 갱신 로직이 비활성 상태였다. 대용량 mesh archive 파일의 S3 업로드가 4시간 이상 소요되면서 초기 발급된 STS 임시 토큰(일반적으로 1시간 만료)이 만료되었고, 갱신 메커니즘이 없어 ExpiredToken 에러가 발생했다.

Technical Analysis#

Code Path#

  • Entry point: mesh-service.ts:101MeshService.run() 호출
  • 실행 단계: Forge 인증 → mesh 추출 → archive 생성 → S3 업로드
  • Failure point: aws-s3.manager.ts:104 — S3 upload callback에서 ExpiredToken 에러 수신

Mesh service의 업로드 플로우:

packages/cupix-tesla-mesh-agent/src/mesh-service.ts:254-288typescript
private uploadBimMeshArchiveFile = async (cpBim: CPBim): Promise<void> => {
    if (cpBim.meshArchiveFilePath ===  undefined) {
        throw new Error('MeshService::uploadBimMeshArchiveFile - not found mesh');
    }

    this.awsS3Manager.resetS3Info();
    const s3Credentials = await this.createMeshResourceCredentials(cpBim);

    // ... credential validation ...

    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
    });

    // NOTE: setApiCreateCredentials is NEVER called here
    await this.awsS3Manager.uploadFileStreamToS3({ ... });
};

checkToken이 no-op이 되는 이유:

packages/base/src/manager/aws-s3.manager.ts:61-80typescript
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이면 항상 early return
    }

    const _credentials = await this._createCredentials();
    this.setCredentials({ ... });
};

_createCredentialsundefined이므로 토큰이 만료되어도 갱신이 불가능하다.

다른 agent들의 올바른 패턴 (potree agent 예시):

packages/cupix-tesla-potree-agent/src/potree-service.ts:364typescript
awsS3Manager.setApiCreateCredentials(() => this.cupixApi.pointcloud.createPotreeUploadCredentials(cpPointcloud.id));

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-any-mesh-agent "zyn5iw"
Time range: 2026-05-22T00:00:00Z to 2026-05-22T11:30:00Z

업로드 시작 시점:

json
{
  "timestamp": "2026-05-22 15:10:17 KST",
  "status": "info",
  "message": "AwsS3Manager::uploadFileStreamToS3 | begin - filePath: /tmp/workspace/18044/mesh_archive/18044.zip, bucketPath: cupixworks-source-b169da1a0187-mece1/resources/zyn5iw/mece1/v15"
}
json
{
  "timestamp": "2026-05-22 15:10:17 KST",
  "status": "info",
  "message": "AwsS3Manager::setCredentials | end"
}

업로드 실패 시점 (약 4시간 후):

json
{
  "timestamp": "2026-05-22 19:11:15 KST",
  "status": "error",
  "message": "MeshService::run | error: {\"stack\":\"ExpiredToken: The provided token has expired.\\n    at Request.extractError (/tmp/agent/dist/node_modules/.pnpm/aws-sdk@2.1599.0/node_modules/aws-sdk/lib/services/s3.js:712:35)\\n    ...\",\"message\":\"The provided token has expired.\",\"code\":\"ExpiredToken\",\"statusCode\":400,\"retryable\":true}"
}

setCredentials(15:10:17) → upload failed(19:11:15) = 약 4시간 경과. STS 토큰 기본 만료 시간(1시간)을 크게 초과.

추가 검증 — 지난 8일간 ExpiredToken 검색:

text
service:cupixworks-any-mesh-agent status:error "ExpiredToken"
Time range: 2026-05-15T00:00:00Z to 2026-05-23T00:00:00Z

결과: 이 인시던트의 2건만 확인됨 (동일 이벤트의 두 로그 라인). 빈번하지 않은 이슈로, 대용량 mesh archive 업로드 시에만 발생.

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 setApiCreateCredentials 미호출로 인한 토큰 갱신 불가 — 장시간 업로드 중 토큰 만료 mesh-service.ts에 setApiCreateCredentials 호출 없음. 다른 6개 agent는 모두 호출함. 업로드 begin→fail 4시간 경과. Confirmed
H2 Tesla API의 credential 발급 시 만료 시간이 너무 짧게 설정됨 expires_at이 코드에서 설정되고 STS 토큰 기본값은 1시간 4시간 소요 — 어떤 STS 설정이든 만료됨. 근본 원인은 갱신 미구현 Rejected
H3 네트워크 문제로 업로드가 비정상적으로 지연됨 4시간이 걸린 것은 비정상적. 대용량 파일 + 느린 네트워크 가능성 다른 업로드는 수 초~수 분 내 완료됨 (동일 시간대 setCredentials 로그 간격 확인). 네트워크 문제여도 토큰 갱신이 없으면 실패 불가피 Contributing factor

Fix Recommendation#

즉시 조치 (Critical)#

  • packages/cupix-tesla-mesh-agent/src/mesh-service.ts:259 (resetS3Info() 이후)에 setApiCreateCredentials 호출 추가
  • 콜백으로 this.cupixApi.bim.createResourceUploadCredentials(cpBim.id, 'mesh') 사용
  • 이를 통해 checkToken()이 업로드 중 토큰 만료 시 자동 갱신 가능

단기 개선 (1주 이내)#

  • uploadFileStreamToS3에서 checkToken은 업로드 시작 전에만 호출됨 — 장시간 업로드 중간에는 갱신 불가. AWS SDK v2의 ManagedUpload가 multipart upload 시 각 part마다 credential을 확인하도록 credential provider를 활용하는 방안 검토
  • 대용량 파일의 경우 multipart upload 사용 확인 (aws-sdk의 upload()는 기본적으로 multipart를 사용하지만, credential 갱신은 별도)

장기 개선 (재발 방지)#

  • AWS SDK v2 → v3 마이그레이션 검토. v3는 credential provider chain이 자동으로 만료 전 갱신 처리
  • 모든 agent의 S3 업로드 코드에서 setApiCreateCredentials 호출 여부를 lint rule이나 코드 리뷰 체크리스트로 검증

Monitoring#

  • ExpiredToken 에러 발생 시 알림 추가:
text
service:cupixworks-any-mesh-agent status:error "ExpiredToken"
  • 업로드 시간 메트릭 — begin과 end/failed 간 시간 차이 모니터링으로 비정상 장시간 업로드 감지

Risk Assessment#

  • Risk level: low (단건 발생, 대용량 mesh 파일에서만 트리거)
  • 예상 복잡도: trivial (setApiCreateCredentials 1줄 추가)