You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Windows NTFS에서 ACL hardening이 5초 후 ETIMEDOUT으로 실패하며 파일시스템 미지원으로 오인 표시됨 #160
Windows 11의 정상적인 로컬 NTFS 볼륨에서 OpenCodex 사용 중 아래 오류가 간헐적으로 발생했습니다.
ACL hardening failed (ETIMEDOUT) — filesystem may not support per-user NTFS ACLs
오류 발생 후 확인한 대상은 로컬 고정 NTFS 볼륨이었고 볼륨 상태도 정상이었습니다. icacls 조회는 약 9~16ms에 정상 완료됐으며, ~/.opencodex와 주요 파일은 현재 사용자 단독 Full Control 상태로 정상 hardening되어 있었습니다.
설치본의 src/lib/windows-secret-acl.ts를 확인하면 runIcacls()가 아래 세 명령을 각각 고정 5초 timeout으로 실행합니다.
/inheritance:r
broad grant SID 제거
현재 사용자 /grant:r
이 중 하나가 5초를 넘기면 Node/Bun의 execFileSync()가 ETIMEDOUT를 반환하지만, sanitizeDiagnostics()는 원인과 관계없이 “filesystem may not support per-user NTFS ACLs”라는 동일한 문구를 출력합니다.
따라서 ACL을 정상 지원하는 NTFS에서도 일시적인 icacls.exe 지연이 파일시스템 미지원처럼 표시되고, required: true인 설정/비밀 파일 쓰기 경로는 실패할 수 있습니다. 뒤 단계에서 timeout이 발생하면 앞 단계만 적용된 부분 상태가 남을 가능성도 있습니다.
기대 동작은 다음과 같습니다.
ETIMEDOUT와 실제 ACL 미지원/권한 오류를 구분해서 표시
timeout 시 제한적인 재시도 후 ACL 상태를 검증
5초 제한을 늘리거나 설정 가능하게 함
기존 required: true의 fail-closed 보안 동작은 유지
Reproduction
간헐적인 현상이라 현재는 안정적으로 반복 재현되지 않습니다.
Windows 11의 로컬 NTFS 드라이브에 OpenCodex 2.7.25를 설치합니다.
opencodex start로 실행합니다.
OpenCodex를 사용하면서 설정/상태 파일 쓰기가 발생합니다.
간헐적으로 위 ACL hardening 오류가 표시됩니다.
같은 볼륨과 경로에서 icacls를 다시 실행하면 수십 ms 이내에 정상 완료됩니다.
Logs and screenshots
ACL hardening failed (ETIMEDOUT) — filesystem may not support per-user NTFS ACLs
OpenCodex: 2.7.25
Node.js: v24.15.0
OS: Microsoft Windows 11 Pro 64-bit, 10.0.26200 (build 26200)
Volume: local fixed disk, NTFS, Healthy, OperationalStatus=OK
Post-incident icacls query: 9–16ms, exit code 0
Current ACL: <USER> only, Full Control
개인정보 보호를 위해 실제 사용자명과 홈 경로는 <USER>로 치환했습니다. ~/.opencodex/crash.log에는 해당 메시지가 기록되어 있지 않아 어느 secret path/단계에서 timeout이 발생했는지는 확인할 수 없었습니다.
Area
CLI
Version
2.7.25
OS
Microsoft Windows 11 Pro 64-bit, 10.0.26200 (build 26200)
Config shape
특정 provider 또는 routing 설정에 의존하는 것으로 보이지 않습니다. 설정과 비밀 값은 첨부하지 않았습니다.
동일한 Windows 11 / OpenCodex 2.7.25 환경에서 ocx stop을 실행하자 프록시 프로세스 종료 후 Codex 원상복구 단계에서 기존 오류가 다시 재현됐습니다.
ACL hardening failed (ETIMEDOUT) — filesystem may not support per-user NTFS ACLs
at hardenSecretPath (.../src/lib/windows-secret-acl.ts:136:17)
at harden (.../src/config.ts:76:39)
at atomicWriteFile (.../src/config.ts:86:8)
at restoreCodexCatalog (.../src/codex/catalog.ts:1926:5)
at restoreNativeCodex (.../src/codex/inject.ts:550:15)
at handleStop (.../src/cli/index.ts:307:13)
결과적으로 프록시는 종료됐지만 ocx stop은 exit code 1을 반환했고, 네이티브 Codex 복구가 중간에 실패했습니다. 이후 ocx ensure는 정상 완료됐습니다. 이 볼륨은 앞서 확인한 것처럼 로컬 NTFS/Healthy이며 평상시 icacls 조회는 수십 ms 이내입니다.
따라서 5초 고정 timeout은 단순 경고가 아니라 stop/restore 트랜잭션을 부분 완료 상태로 만들 수 있습니다. restore 작업에서는 timeout 재시도와 최종 ACL 검증, 실패 시 journal 기반 rollback/복구 상태 안내가 필요해 보입니다.
2. 계정 풀 로그인에서 이전 ChatGPT 임시 토큰이 재사용되는 별도 상태 버그
같은 세션에서 풀에 다른 ChatGPT 계정을 추가하려 할 때, 시크릿 창과 별도 브라우저 프로필을 사용해도 다음 오류가 반복됐습니다.
Account is already in the pool (chatgpt-1784451703998).
조사 결과 새 로그인 시도 후에도 ~/.opencodex/auth.json의 수정 시각과 토큰 세대가 바뀌지 않았는데, 오류는 기존 임시 슬롯의 계정을 계속 가리켰습니다.
현재 코드 흐름은 다음과 같습니다.
getLoginStatus()는 현재 OAuth flow의 성공 여부와 독립적으로 기존 auth.json credential이 있으면 loggedIn: true를 반환합니다.
새 OAuth flow가 실패하면 상태가 done: true, error: ..., loggedIn: true가 될 수 있습니다.
Status: partially mitigated on dev by a676f80b (landed while absorbing PR #157):
ETIMEDOUT is now distinguished from real ACL failures — only genuine timeouts soft-fail on required: true paths (with a warning), while real EPERM/EACCES/non-zero exits still fail closed;
the stacked per-command timeouts that could stall loadConfig for minutes are replaced with one shared 5s deadline per harden call, and a timed-out path is not re-attempted every call;
swallowed /remove:g failures are now verified with locale-independent icacls /findsid before being accepted.
Still open from this report (why this issue stays open):
the timeout diagnostic still reads "filesystem may not support per-user NTFS ACLs" — misleading for a transient icacls stall on a healthy volume;
no bounded retry + final ACL-state verification after a timeout (the partial-state concern in the report);
the 5s budget is not configurable.
These will be addressed in a follow-up; leaving this open to track them.
Fixed on dev by 3183a990 (completing the partial mitigation from a676f80b):
진단 문구 분리: ETIMEDOUT은 이제 "ACL hardening timed out (ETIMEDOUT) — transient icacls stall; the volume may still support per-user NTFS ACLs"로 표시됩니다. filesystem-unsupported 문구는 실제 icacls 명령 오류(EICACLS)에만 사용되고, EPERM/EACCES는 permission denied로 구분됩니다.
재시도 + 상태 검증: required 경로에서 타임아웃이 나면 동일한 총 예산 안에서 1회 재시도합니다. 재시도도 타임아웃이면 icacls /findsid로 broad SID 상태를 진단해 soft-fail 메시지에 명시합니다("broad ACL grants still present" / "no broad grants detected — hardening still incomplete"). 검증은 진단 전용이며, 완전한 hardening 시퀀스가 끝난 경우에만 성공으로 기록됩니다 — 부분 상태가 hardened로 오인되지 않습니다.
제한 설정화: OPENCODEX_ACL_TIMEOUT_MS 환경변수로 총 예산을 조정할 수 있습니다(기본 5000ms, 1000–60000 범위로 클램프). 재시도·검증을 포함한 전체 예산이라 loadConfig 연쇄 스톨은 재발하지 않습니다.
required: true의 fail-closed 동작은 유지됩니다: 진짜 EPERM/EACCES/명령 오류는 여전히 throw합니다.
dev CI green (Cross-platform CI). 다음 릴리스에 포함됩니다. 리포트 감사합니다 — 세 가지 기대 동작 전부 반영했습니다.
Activity
Love0118 commentedon Jul 19, 2026
추가 조사 및 임시 조치 결과를 공유합니다.
1.
ocx stop에서 ACL timeout 재현동일한 Windows 11 / OpenCodex 2.7.25 환경에서
ocx stop을 실행하자 프록시 프로세스 종료 후 Codex 원상복구 단계에서 기존 오류가 다시 재현됐습니다.결과적으로 프록시는 종료됐지만
ocx stop은 exit code 1을 반환했고, 네이티브 Codex 복구가 중간에 실패했습니다. 이후ocx ensure는 정상 완료됐습니다. 이 볼륨은 앞서 확인한 것처럼 로컬 NTFS/Healthy이며 평상시icacls조회는 수십 ms 이내입니다.따라서 5초 고정 timeout은 단순 경고가 아니라 stop/restore 트랜잭션을 부분 완료 상태로 만들 수 있습니다. restore 작업에서는 timeout 재시도와 최종 ACL 검증, 실패 시 journal 기반 rollback/복구 상태 안내가 필요해 보입니다.
2. 계정 풀 로그인에서 이전 ChatGPT 임시 토큰이 재사용되는 별도 상태 버그
같은 세션에서 풀에 다른 ChatGPT 계정을 추가하려 할 때, 시크릿 창과 별도 브라우저 프로필을 사용해도 다음 오류가 반복됐습니다.
조사 결과 새 로그인 시도 후에도
~/.opencodex/auth.json의 수정 시각과 토큰 세대가 바뀌지 않았는데, 오류는 기존 임시 슬롯의 계정을 계속 가리켰습니다.현재 코드 흐름은 다음과 같습니다.
getLoginStatus()는 현재 OAuth flow의 성공 여부와 독립적으로 기존auth.jsoncredential이 있으면loggedIn: true를 반환합니다.done: true,error: ...,loggedIn: true가 될 수 있습니다.src/codex/auth-api.ts의 polling loop는st.done && st.loggedIn을st.done && st.error보다 먼저 검사합니다.getCredential("chatgpt")로 다시 읽어 중복 계정 판정을 수행합니다.관련 분기는 현재 다음 순서입니다.
적용한 임시 우회책
~/.opencodex/auth.json을 삭제하지 않고auth.json.stale-chatgpt-<timestamp>.bak으로 백업 이동codex-accounts.json의 SHA-256을 전후 비교하여 변경되지 않았음을 확인ocx ensure후/healthz정상 및 OpenCodex 2.7.25 기동 확인이렇게 하면 기존 풀 계정은 보존하면서 이전 ChatGPT scratch slot만 제거할 수 있습니다.
제안 수정
st.done && st.error를 성공 분기보다 먼저 처리Account is already in the pool대신 원래 OAuth 오류를 반환토큰, 전체 이메일, 사용자명 및 개인 경로는 모두 제외하거나 마스킹했습니다.
Wibias commentedon Jul 19, 2026
@lidge-jun Already started a fix on that earliert, cause i had the same problem with kimi and other stuff.
#157
Love0118 commentedon Jul 19, 2026
동일 오류가 다시 발생해 추가 진단과 로컬 핫픽스를 적용했습니다.
반복 발생 및 진단 결과
auth.json의 이전 ChatGPT scratch slot을 제거한 상태에서도 다음 오류가 다시 발생했습니다.같은 머신과 Bun 1.3.14에서 진단용 파일에 OpenCodex와 동일한 3단계 명령을 반복 실행했습니다.
/inheritance:r/remove:g/grant:ricacls.exe호출로컬 NTFS와 ACL 기능은 정상이며, 오류 문구의 파일시스템 미지원 추정은 실제 환경과 맞지 않습니다. 간헐적인 child-process/pipe 완료 지연이 5초 고정 timeout과 결합된 것으로 보입니다.
적용한 로컬 핫픽스
설치된 2.7.25의
src/lib/windows-secret-acl.ts에 다음 변경을 적용했습니다.stdio: "ignore"로 변경ETIMEDOUT에 한해 동일한 idempotenticacls명령을 1회 재시도ACL hardening timed out after retrying icacls반환패치된 모듈을 별도 Bun 프로세스에서 직접 import하여
hardenSecretPath(..., { required: true })를 실행했고 약 29ms에 성공했습니다.재기동 안전성
현재 Codex 세션 자체가 OpenCodex 프록시를 경유하므로 단순
ocx stop은 활성 세션을 끊을 수 있습니다. 이를 피하기 위해 별도 hidden watchdog 프로세스가 다음 순서를 끝까지 수행하도록 했습니다.결과:
ocx stop의 Codex 복구 단계에서도 이번에는 ACL timeout 없음이 핫픽스는 npm 패키지 업데이트 시 덮어써지는 임시 조치입니다. upstream에서는 retry/timeout 정책과 정확한 진단 문구를 정식으로 반영하는 것이 좋겠습니다.
Love0118 commentedon Jul 19, 2026
로컬 핫픽스 후속 수정입니다.
icacls.exe의 stdout pipe를stdio: "ignore"로 바꾼 상태에서 Windows GUI/백그라운드 프로세스가 console child를 생성할 때 창이 순간적으로 표시될 수 있었습니다.execFileSync()옵션에 다음을 추가했습니다.windowsHide: true패치된 모듈의 실제 ACL 3단계 호출은 약 52ms에 성공했고, hidden watchdog으로 프록시 중단 후 재기동을 보장했습니다. 새 프록시는 포트 10100에서 health 정상이며 watchdog stderr는 비어 있습니다.
upstream에서 stdout pipe 제거를 채택한다면 Windows의
windowsHide: true도 함께 적용해야 합니다.Wibias commentedon Jul 19, 2026
@SIMJAEYUN001 이 문제를 해결할 수 있는 PR이 이미 열려 있으니, 제 위 댓글에서 확인해 보세요.
lidge-jun commentedon Jul 19, 2026
im reviewing and merging one by one in local
lidge-jun commentedon Jul 19, 2026
Status: partially mitigated on
devbya676f80b(landed while absorbing PR #157):ETIMEDOUTis now distinguished from real ACL failures — only genuine timeouts soft-fail onrequired: truepaths (with a warning), while realEPERM/EACCES/non-zero exits still fail closed;loadConfigfor minutes are replaced with one shared 5s deadline per harden call, and a timed-out path is not re-attempted every call;/remove:gfailures are now verified with locale-independenticacls /findsidbefore being accepted.Still open from this report (why this issue stays open):
icaclsstall on a healthy volume;These will be addressed in a follow-up; leaving this open to track them.
fix(windows): honest timeout diagnostics, bounded retry, and configur…
lidge-jun commentedon Jul 19, 2026
Fixed on
devby3183a990(completing the partial mitigation froma676f80b):ETIMEDOUT은 이제 "ACL hardening timed out (ETIMEDOUT) — transient icacls stall; the volume may still support per-user NTFS ACLs"로 표시됩니다. filesystem-unsupported 문구는 실제 icacls 명령 오류(EICACLS)에만 사용되고, EPERM/EACCES는 permission denied로 구분됩니다.icacls /findsid로 broad SID 상태를 진단해 soft-fail 메시지에 명시합니다("broad ACL grants still present" / "no broad grants detected — hardening still incomplete"). 검증은 진단 전용이며, 완전한 hardening 시퀀스가 끝난 경우에만 성공으로 기록됩니다 — 부분 상태가 hardened로 오인되지 않습니다.OPENCODEX_ACL_TIMEOUT_MS환경변수로 총 예산을 조정할 수 있습니다(기본 5000ms, 1000–60000 범위로 클램프). 재시도·검증을 포함한 전체 예산이라 loadConfig 연쇄 스톨은 재발하지 않습니다.required: true의 fail-closed 동작은 유지됩니다: 진짜 EPERM/EACCES/명령 오류는 여전히 throw합니다.dev CI green (Cross-platform CI). 다음 릴리스에 포함됩니다. 리포트 감사합니다 — 세 가지 기대 동작 전부 반영했습니다.
fix(windows): honest timeout diagnostics, bounded retry, and configur…