ES /docs

QMAws::startTask | ECS failures - job_id: 1025611, task_definition: cupix-pano-postprocessor-product

RCA: QMAws::startTask | ECS failures - AGENT reason

Overview#

What Happened#

2026-04-20 23:25:44 UTC에 cupixworks-any-compute-agent 서비스에서 ECS startTask API 호출 시 container instance의 ECS agent 연결 문제로 인해 task 배치가 실패했다. 해당 job(1025611)은 약 3분 후 동일 container instance에서 재시도되어 성공적으로 실행되었다.

Quick Facts#

Field Value
exception.class ECS StartTask Failure
exception.message failures: [{"arn":"...100968f2df2748a8920b1944be34a4cf","reason":"AGENT"}]
top_frame qmAws.ts:197
env production, us-west-2

Timeline#

  1. 2026-04-20T23:25:44Z — Job 1025611 첫 번째 runTask 시도. container instance 100968f2 선택 (ACTIVE, memory 30940 MiB, running 0, pending 0). startTask 호출 시 reason: "AGENT" failure 반환.
  2. 2026-04-20T23:25:44Z — 같은 시각 다른 container instances (e8ca99cf, 6c72fa66)도 평가되었으나 pendingTasksCount == 1이어서 건너뜀. SQS 메시지 삭제되지 않음.
  3. 2026-04-20T23:27:23Z — 두 번째 재시도. 동일 상황 — 다른 instances에 pending tasks 존재하여 task size 0으로 종료.
  4. 2026-04-20T23:29:07Z — 세 번째 시도. container instance 100968f2가 이제 정상 복구됨 (running 0, pending 0). startTask 성공, task ARN ae3c04e78ef9... 할당.

Error Log#

Datadog Logs

text
QMAws::startTask | ECS failures - job_id: 1025611, task_definition: cupix-pano-postprocessor-production, cluster: cupix-tesla-ece, container_instance: arn:aws:ecs:us-west-2:002596530511:container-instance/cupix-tesla-ece/100968f2df2748a8920b1944be34a4cf, failures: [{"arn":"arn:aws:ecs:us-west-2:002596530511:container-instance/100968f2df2748a8920b1944be34a4cf","reason":"AGENT"}]

Impact#

  • Service: cupixworks-any-compute-agent
  • Team: swinerton
  • 발생 횟수: 1 (이 클러스터), 10+ (지난 7일간 동일 패턴)
  • 최초 발생: 2026-04-20T23:25:44.515Z
  • 최근 발생: 2026-04-20T23:25:44.515Z

이 에러 자체는 자동 복구되었다. Job 1025611은 약 3분 지연 후 성공적으로 실행됨. 사용자 영향은 pano postprocessor 작업의 일시적 지연에 한정된다.

Root Cause Summary#

ECS startTask API가 reason: "AGENT" failure를 반환한 것은 대상 container instance의 ECS Agent가 일시적으로 ECS 컨트롤 플레인과 통신 불가 상태였기 때문이다. ECS Agent가 disconnected 상태이면 AWS는 해당 instance에 task를 배치하지 못하고 AGENT reason을 반환한다. 이는 EC2 인스턴스 자체가 정상 상태(ACTIVE, 리소스 가용)더라도 Agent 프로세스의 일시적 연결 끊김이나 재시작 중 발생할 수 있는 인프라 수준의 transient failure이다. 약 3분 후 Agent가 재연결되어 동일 instance에서 task가 성공했다.

Technical Analysis#

Code Path#

  • Entry point: job.manager.ts:49checkingQueue에서 SQS 메시지 수신
  • job.manager.ts:91runJob 에서 job 초기화 및 runTask 호출
  • qmAws.ts:117runTask에서 container instances 조회 및 반복
qmAws.ts:134-160typescript
} else {
    const containerInstances = await this.describeContainerInstances(awsClusterName, containerInstanceArns);
    logger.info('QMAws::runTask | containerInstances size: %d', containerInstances.length);
    for await (const containerInstance of containerInstances) {
        // ... resource logging ...
        if (containerInstance.status == 'ACTIVE'
            && containerInstance.runningTasksCount == 0
            && containerInstance.pendingTasksCount == 0
        ) {
            try {
                tasks = await this.startTask(awsClusterName, containerInstance.containerInstanceArn as string, job);
                if (tasks.length > 0) break;
            } catch (error) {
                return;  // startTask reject시 즉시 반환 — 다른 instance 시도 안 함
            }
        }
    }
}
  • Failure point: qmAws.ts:191-203startTask 콜백에서 data.failures 확인
qmAws.ts:191-213typescript
this.ecs.startTask(params, (err, data) => {
    if (err) {
        logger.error('QMAws::startTask | end - %s', err.message);
        reject(err);
    } else {
        if (data.failures && data.failures.length > 0) {
            logger.error('QMAws::startTask | ECS failures - job_id: %d, task_definition: %s, cluster: %s, container_instance: %s, failures: %s',
                job.id, taskDefinition, awsClusterName, containerInstanceArn,
                JSON.stringify(data.failures.map(f => ({ arn: f.arn, reason: f.reason, detail: f.detail })))
            );
        }
        const tasks = data.tasks;
        if (tasks == undefined) {
            logger.info('QMAws::startTask | end - task empty');
            resolve([]);
        } else {
            resolve(tasks);
        }
    }
});

기대 동작: container instance가 ACTIVE이고 running/pending 0이면 task 배치 성공. 실제 동작: AWS API가 성공 응답(err=null)을 반환하되, data.failuresAGENT reason이 포함됨. data.tasks는 빈 배열 또는 undefined → resolve([])로 처리. error log는 남기되 reject하지는 않음.

  • Recovery path: job.manager.ts:120updateTaskIdToJob에서 tasks.length === 0이면 resolve(false) 반환
qmJob.ts:163-174typescript
updateTaskIdToJob = (qmAws: QMAws, clusterName: string, tasks?: AWS.ECS.Task[]): Promise<boolean> => new Promise(resolve => {
    const jobId = this.id;
    if (tasks == undefined) {
        return resolve(true);  // undefined면 done=true → 메시지 삭제됨
    }
    const taskLength = tasks.length;
    logger.info('QMJob::updateTaskIdToJob | begin - job id: %d, task length: %d', jobId, taskLength);
    if (taskLength === 0) {
        return resolve(false);  // 빈 배열이면 done=false → 메시지 삭제 안 됨
    }

done=false이면 SQS 메시지가 삭제되지 않아 visibility timeout 후 재처리된다. 이것이 자동 재시도 메커니즘이다.

Log Evidence#

사용한 Datadog 쿼리:

text
service:cupixworks-any-compute-agent "1025611"
Time: 2026-04-20T22:00:00Z to 2026-04-21T01:00:00Z

첫 번째 시도 (23:25:44Z) — 실패:

text
QMAws::runTask | job_id: 1025611, container_instance: arn:aws:ecs:us-west-2:002596530511:container-instance/cupix-tesla-ece/100968f2df2748a8920b1944be34a4cf, status: ACTIVE, available_memory_mib: 30940, available_cpu: 8192, running_tasks: 0, pending_tasks: 0
QMAws::startTask | ECS failures - job_id: 1025611, task_definition: cupix-pano-postprocessor-production, cluster: cupix-tesla-ece, container_instance: ...100968f2df2748a8920b1944be34a4cf, failures: [{"arn":"...100968f2df2748a8920b1944be34a4cf","reason":"AGENT"}]
QMAws::runTask | end - job id: 1025611, task size: 0
QMJob::updateTaskIdToJob | begin - job id: 1025611, task length: 0

세 번째 시도 (23:29:07Z) — 성공:

text
QMAws::runTask | job_id: 1025611, container_instance: arn:aws:ecs:us-west-2:002596530511:container-instance/cupix-tesla-ece/100968f2df2748a8920b1944be34a4cf, status: ACTIVE, available_memory_mib: 30940, available_cpu: 8192, running_tasks: 0, pending_tasks: 0
QMAws::runTask | end - job id: 1025611, task size: 1
QMJob::updateTaskIdToJob | begin - job id: 1025611, task length: 1
QMJob::updateTaskIdToJob | end - job id: 1025611, task arn: arn:aws:ecs:us-west-2:002596530511:task/cupix-tesla-ece/ae3c04e78ef94789815ac9803833dbdc

과거 7일간 동일 패턴 (다양한 container instances 및 task definitions):

text
service:cupixworks-any-compute-agent status:error "reason\":\"AGENT"
Time: 2026-04-14T00:00:00Z to 2026-04-21T01:00:00Z
Result: 10+ occurrences across instances: 100968f2, 0e01ed02, 8536e537, 32d0093f, 75e93090, 8984c10a, 3c0e9ec4
Task definitions affected: cupix-pano-postprocessor-production, cupix-skat-master-production-arm, cupix-capture-3d-reconstruction-production, cupix-capture-refinement-production-arm

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 ECS Agent가 일시적으로 disconnected 상태여서 task 배치 불가 AWS 문서에서 reason: "AGENT"는 Agent 연결 불가를 의미. Instance는 ACTIVE 상태이나 task 배치 실패. 3분 후 동일 instance에서 성공 — Agent 재연결 확인 Confirmed
H2 Container instance의 리소스 부족으로 task 배치 실패 로그에서 available_memory_mib: 30940, available_cpu: 8192, running_tasks: 0으로 확인. 리소스 충분 Rejected
H3 Task definition 설정 오류 (이미지 pull 실패 등) 동일 task definition이 3분 후 같은 instance에서 성공. 다른 instances에서도 동일 task def 정상 실행 Rejected
H4 코드 버그 — startTask 후 failure를 reject하지 않아 silent failure data.failures 있을 때 error 로그만 남기고 resolve([])로 처리. 하지만 이는 의도된 동작 — SQS 재시도를 통한 recovery path 실제로 재시도되어 성공함 Rejected (현 동작은 의도적)

Fix Recommendation#

즉시 조치 (Critical)#

  • 조치 불필요. 이 에러는 AWS 인프라 수준의 transient failure이며, 현재 코드의 SQS 재시도 메커니즘이 정상 작동하여 자동 복구됨.

단기 개선 (1주 이내)#

  • 로그 레벨 조정: qmAws.ts:197logger.errorlogger.warn으로 변경 고려. reason: "AGENT"는 자동 복구되는 transient failure이므로 error 레벨보다 warn이 적절함. 이렇게 하면 불필요한 error alert noise를 줄일 수 있음.
  • 파일: applications/agents/packages/cupix-tesla-compute-agent/src/model/qmAws.ts:197

장기 개선 (재발 방지)#

  • 다른 instance fallback: 현재 startTask 실패 시 resolve([])를 반환하고 loop에서 tasks.length > 0이면 break — 즉 failure 후에도 다음 instance를 시도함. 그러나 모든 적격 instance의 ECS Agent가 동시에 문제일 경우를 대비하여, runTask 결과가 빈 배열일 때 짧은 delay 후 즉시 재시도하는 로직을 추가하면 SQS visibility timeout(기본 30초)을 기다리지 않고 더 빠르게 복구할 수 있음.
  • ECS Agent health monitoring: Container instance의 Agent 상태를 주기적으로 확인하고, 장기간 disconnected인 instance를 자동으로 drain/교체하는 운영 자동화 고려.

Monitoring#

  • ECS AGENT failure 빈도 추적:
text
service:cupixworks-any-compute-agent status:error "reason\":\"AGENT"
  • 특정 container instance에서 반복 발생 시 알림:
text
service:cupixworks-any-compute-agent "reason\":\"AGENT" @container_instance:*

Risk Assessment#

  • Risk level: low
  • 예상 복잡도: trivial — 로그 레벨 변경만으로 alert noise 감소 가능. 자동 복구가 이미 동작하므로 기능적 수정은 불필요.