플레이스토어 versionCode 중복 오류 해결법 — 로컬 값을 믿으면 안 되는 이유
- 공유 링크 만들기
- X
- 이메일
- 기타 앱

앱을 올리려는데 "이 버전 코드는 이미 사용되었습니다" 가 뜨고, 코드를 올려서 다시 올려도 또 같은 말이 나온다면 — 로컬 파일의 숫자를 보고 계셔서 그렇습니다. 그 숫자는 진실이 아니에요.
제 안드로이드 앱 저장소에서 이 오류와 씨름한 흔적을 그대로 뽑았습니다. 하루에 번호를 여덟 번 고쳤고, 그중 한 번은 100에서 56으로 내려갔습니다.
📌 3줄 결론
- Play는 한 번 업로드한 versionCode를 영구히 소진합니다. 그 버전을 지워도 번호는 안 돌아옵니다
- 로컬build.gradle의 숫자는 "내가 마지막에 적은 것"이지 "Play가 아는 것"이 아닙니다
- 고치는 순서는 Play Console에서 실제 최대값을 먼저 확인하고, 그보다 큰 수를 적는 겁니다. 반대로 하면 반복됩니다
확인일 2026-08-14 · 대상: 제가 직접 운영하는 안드로이드 앱 저장소
작성·검증 방식
ARION 운영자가 Git 커밋 이력과 현재 모듈 설정을 직접 대조했습니다. AI는 기록을 표와 설명 순서로 정리하는 데만 보조로 사용했고, 숫자와 날짜는 비밀값을 제거한 로컬 증거 파일play-versioncode-conflict-2026-08-14.txt및 Android·Play 공식 문서로 재확인했습니다.
왜 이 오류가 나나
versionCode 는 사람이 읽는 버전 이름과 다릅니다. versionName 이 "1.0.47" 같은 표시용 문자열이라면, versionCode 는 Play가 어느 쪽이 더 새 빌드인지 판단하는 정수입니다.
규칙은 두 개입니다. 새로 올리는 빌드는 이전보다 큰 수여야 하고, 한 번 쓴 수는 다시 못 씁니다. 업로드를 취소하거나 그 버전을 비활성화해도 번호는 반환되지 않아요.
여기서 오해가 생깁니다. "내 컴퓨터에서 50까지 썼으니 51을 넣으면 되겠지"라고 생각하는데, 그동안 CI가 빌드해서 올렸거나 다른 트랙에 테스트 버전을 올렸으면 Play 쪽 숫자는 훨씬 앞서 있습니다.
실제로 무슨 일이 있었나
제 저장소의 build.gradle 변경 이력만 뽑았습니다. 왼쪽이 바뀌기 전, 오른쪽이 바뀐 뒤입니다.
2026-08-06 50 → 51
2026-08-06 51 → 55 "51은 Play에서 이미 사용됨"
2026-08-06 55 → 100 "51·55 모두 Play에서 사용 중"
2026-08-06 100 → 56
2026-08-06 56 → 57
2026-08-06 57 → 58
2026-08-06 58 → 59
2026-08-11 59 → 101
하루에 여덟 번입니다. 그리고 네 번째 줄을 보세요. 100까지 올렸다가 56으로 내려갔습니다.
왜 내려갔는지는 커밋 메시지에 없어서 지금은 알 수 없습니다. 다만 Play의 규칙이 "이전보다 큰 수"이므로, 소스에서 번호가 내려가는 자국이 남았다는 것 자체가 그 시점에 무언가 꼬여 있었다는 신호입니다.
이게 처음도 아니었습니다. 훨씬 전부터 같은 일이 있었어요.
2026-06-15 versionCode 12 (1.0.7) — Play 버전코드 10/11 충돌 회피
2026-07-04 versionCode 40 (1.0.34) — Play Console 39 중복 거부로 재상향
충돌 기록이 최소 네 번(10·11, 39, 51, 55)입니다. 같은 실수를 두 달에 걸쳐 반복한 겁니다.
재현 근거 카드
| 질문 | 저장소에서 확인한 증거 | 판정 한계 |
|---|---|---|
| 값이 실제로 반복 변경됐나 | 2026-08-06 변경 8회 | 커밋되지 않은 로컬 시도는 포함하지 않음 |
| 값이 내려간 적이 있나 | 100 → 56 기록 | 내려간 이유는 커밋 메시지에 없어 단정하지 않음 |
| 과거에도 충돌했나 | 10·11, 39, 51, 55 충돌 언급 | Play Console 전체 업로드 이력을 직접 내보낸 것은 아님 |
| 모듈 값이 같은가 | app 101 · wear 1 | 두 모듈의 배포 정책이 같은지는 별도 확인 필요 |
따라서 이 글의 핵심 근거는 “Play Console에 현재 몇 번이 있다”는 추정이 아니라, 로컬 번호만 믿고 반복 수정했던 저장소 기록입니다. 실제 다음 번호는 반드시 본인의 Play Console에서 확인해야 합니다.
로컬 값이 진실이 아닌 이유
build.gradle 의 숫자가 뜻하는 건 딱 하나입니다 — 내가 마지막으로 저장한 값. 그게 Play에 도달했는지, 도달해서 소진됐는지는 그 파일이 모릅니다.
번호가 소진되는 경로가 생각보다 많습니다.
- CI가 자동으로 빌드해 내부 테스트에 올린 경우
- 내부 테스트·비공개 테스트에만 올리고 프로덕션에는 안 올린 경우
- 올렸다가 취소하거나 롤아웃을 중단한 경우
- 다른 사람이나 다른 컴퓨터에서 올린 경우
이 중 어느 것도 로컬 파일에 흔적을 남기지 않습니다. 그래서 로컬 값 +1은 추측이고, 그 추측이 틀리면 같은 오류가 다시 납니다.
제대로 고치는 순서
숫자를 하나씩 올려보며 맞히는 건 방법이 아닙니다. 저는 그렇게 하루에 여덟 번 고쳤습니다.
첫째, Play Console에서 실제로 쓰인 최대값을 확인합니다. 프로덕션만 보면 안 되고 내부 테스트·비공개 테스트·공개 테스트까지 모든 트랙을 봐야 합니다. 앱 번들 탐색기에서 업로드된 목록을 보면 각 항목의 버전 코드가 나옵니다.
둘째, 그 값보다 확실히 큰 수를 적습니다. +1로 아슬아슬하게 붙이지 말고 여유를 두세요. 저는 59에서 101로 갔는데, 이렇게 하면 미확인 업로드가 몇 개 있어도 한 번에 넘어갑니다. versionCode는 아껴 쓸 이유가 없는 자원입니다.
셋째, 그 판단의 근거를 커밋 메시지에 남깁니다. 제 저장소에서 지금 유일하게 남은 기록이 커밋 메시지였습니다. "51은 Play에서 이미 사용됨" 이 한 줄 덕분에 두 달 뒤인 오늘 무슨 일이 있었는지 재구성할 수 있었어요. 다만 이건 운이 좋았던 것이지 설계가 아닙니다.
모듈이 여러 개면 번호도 여러 개다
놓치기 쉬운 자리가 하나 더 있습니다. 제 저장소를 뒤져보니 이랬어요.
android/app/build.gradle:20 versionCode 101
android/wear/build.gradle:12 versionCode 1
앱 모듈은 101까지 갔는데 워치 모듈은 아직 1입니다. 워치 앱을 따로 올리게 되는 날 이 숫자를 그대로 두면 같은 종류의 사고가 처음부터 다시 시작됩니다.
모듈이 여러 개인 프로젝트라면 번호를 각각 관리하고 있는지, 아니면 한 곳에서 계산해 내려보내는지 지금 확인해두세요.
직접 확인하는 법
내 저장소가 이 문제를 겪고 있는지 몇 초면 압니다.
지금 값이 얼마인지, 모듈이 몇 개인지 봅니다.
git grep -n versionCode -- "*/build.gradle"
값이 어떻게 오갔는지 이력을 봅니다. 내려간 구간이 있으면 그 시점에 꼬였던 겁니다.
git log --date=short --pretty='---- %ad %h' -p -- android/app/build.gradle | grep -E '^(----|[+-] *versionCode)'
과거에 충돌한 적이 있는지 커밋 메시지에서 찾습니다.
git log --oneline -i --grep=versionCode
앱 배포 오류를 줄이는 관련 글
- 앱 배포 전에 개발자 사이트와 광고 파일을 준비하려면 GitHub Pages로 app-ads.txt를 구축한 실측 기록을 이어서 확인하세요.
- 업로드 직전 Git 저장소 자체가 이상하다면 번호부터 올리지 말고 손상된 오브젝트를 확인하고 복구하는 절차를 먼저 진행하세요.
자주 묻는 질문 (FAQ)
Q. 이미 쓴 번호를 정말 다시 못 쓰나요?
네. 업로드한 순간 소진됩니다. 그 버전을 삭제하거나 비활성화해도 돌아오지 않습니다.
Q. 번호를 크게 건너뛰면 나중에 문제가 되나요?
표시되는 버전 이름과 별개라 사용자는 못 봅니다. 상한이 아주 크므로 실무에서 고갈될 일은 없습니다. 아껴서 생기는 이득보다 충돌로 잃는 시간이 훨씬 큽니다.
Q. 자동으로 올려주면 되지 않나요?
빌드할 때마다 +1 하는 방식은 로컬에서만 도는 한 같은 문제를 그대로 안습니다. 기준이 여전히 "내 컴퓨터가 아는 값"이니까요. 제대로 하려면 Play 쪽 최대값을 조회해서 그 위로 올려야 합니다.
Q. 로컬 브랜치가 여러 개면요?
더 위험합니다. 브랜치마다 다른 숫자를 들고 있으면 어느 쪽에서 빌드했느냐에 따라 값이 달라집니다. 빌드 전에 원격과 비교하는 습관이 필요합니다.
Q. 지금은 해결됐나요?
당장은요. 101로 올려서 통과했습니다. 하지만 구조는 그대로입니다. 여전히 사람이 Play Console을 눈으로 보고 손으로 적습니다. 다음에 미확인 업로드가 하나 생기면 같은 일이 또 납니다.
실행 체크리스트
- 번호를 올리기 전에 Play Console의 모든 트랙에서 최대값을 확인한다
- +1이 아니라 여유를 두고 올린다 — 아낄 이유가 없다
- 왜 그 숫자를 골랐는지 커밋 메시지에 남긴다
git log -p로 값이 내려간 구간이 있는지 확인한다- 모듈이 여러 개면 각각의 번호를 따로 확인한다
- 빌드 전에 로컬 브랜치가 원격보다 뒤처지지 않았는지 본다
- 장기적으로는 사람 기억이 아니라 검사가 막게 만든다
참고한 공식 문서
- 버전 코드와 버전 이름의 차이: 앱 버전 관리
- 업로드 요건과 버전 코드 규칙: Play Console 도움말
- 모듈별 빌드 설정 위치: 앱 모듈 구성
다음 글 예고
다음은 광고를 붙이기 전에 반드시 지나야 하는 동의 게이트입니다. 동의 없이 광고가 나가면 어떻게 되는지, 그리고 웹용 광고 코드가 앱 번들에 섞여 들어가지 않게 막는 장치를 코드로 보여드리겠습니다.
참고 자료
출처 확인일: 2026-08-14
댓글