Docker adalah alat yang sudah menjadi standar de facto dalam dunia containerisasi aplikasi. Namun, seperti halnya teknologi lainnya, Docker tidak luput dari berbagai error yang kerap kali membuat pengguna pusing. Salah satu error yang cukup sering muncul, terutama bagi pengguna yang baru pertama kali mencoba login ke Docker Hub atau registry pihak ketiga, adalah pesan yang bertuliskan "error saving credentials: error storing credentials - err: exit status 1, out: not implemented". Error ini muncul tanpa peringatan, menghentikan proses login, dan membuat image push/pull gagal karena Docker tidak bisa menyimpan autentikasi. Artikel ini akan membongkar error tersebut sampai ke akar-nya, memberikan solusi step-by-step yang langsung bisa kamu praktikkan, serta memastikan error ini tidak muncul lagi di masa depan.


Membaca Pesan Errornya

Ketika kamu menjalankan perintah docker login, alih-alih mendapat pesan Login Succeeded, yang muncul adalah pesan berikut:

Error saving credentials: error storing credentials - err: exit status 1, out: `not implemented`

Pesan ini muncul secara verbatim persis seperti di atas, biasanya setelah kamu memasukkan username dan password yang benar. Docker sebenarnya sudah berhasil melakukan autentikasi ke server registry — username dan password kamu valid — tetapi proses gagal pada tahap menyimpan kredensial tersebut ke dalam credential store lokal.

Dalam bahasa Indonesia, pesan ini berarti: "Gagal menyimpan kredensial: gagal menyimpan kredensial — error: status keluar 1, output: 'belum diimplementasikan'". Status keluar 1 (exit status 1) adalah indikator Unix standar bahwa sebuah proses berakhir dengan kegagalan. Frasa not implemented berasal dari credential helper yang dipanggil oleh Docker, namun helper tersebut tidak memiliki implementasi fungsi penyimpanan — alias kosong atau placeholder.

Kenapa error ini muncul? Jawaban singkatnya: Docker dikonfigurasi untuk menggunakan external credential helper (misalnya docker-credential-desktop, docker-credential-wincred, atau docker-credential-pass), tetapi helper tersebut tidak tersedia, tidak bisa dieksekusi, atau tidak kompatibel dengan sistem tempat Docker berjalan. Ketika Docker mencoba memanggil helper tersebut untuk menyimpan token login, helper merespons dengan not implemented, dan Docker menginterpretasikan ini sebagai kegagalan fatal.

Perhatikan potongan konfigurasi ~/.docker/config.json berikut yang menjadi sumber masalah:

{
  "credsStore": "desktop"
}

Nilai "desktop" menginstruksikan Docker untuk mencari executable docker-credential-desktop di PATH. Jika executable itu tidak ada, rusak, atau tidak berfungsi, maka error di atas pasti muncul.


Sumber Masalahnya

Berikut adalah root cause tersering dari error ini, diurutkan dari yang paling sering ditemui di lapangan:

  1. Credential helper tidak terinstall atau tidak ada di PATH. Ini adalah penyebab paling dominan. Docker Desktop biasanya menginstal credential helper secara otomatis, tetapi jika kamu menggunakan Docker Engine standalone (tanpa Docker Desktop), atau melakukan instalasi manual, helper seperti docker-credential-desktop atau docker-credential-pass bisa saja tidak tersedia. Docker tetap merujuk pada credsStore di config.json, tapi saat binary-nya dicari dan tidak ditemukan, yang dikembalikan adalah pesan not implemented.

  2. Konfigurasi credsStore yang salah atau tidak sesuai dengan OS. Sering terjadi ketika file ~/.docker/config.json di-copy dari mesin lain atau dari tutorial online. Misalnya, konfigurasi "credsStore": "osxkeychain" dipakai di Linux, atau "credsStore": "wincred" dipakai di macOS. Setiap OS memiliki helper yang berbeda, dan ketidakcocokan ini langsung memicu error.

  3. Docker Desktop yang rusak atau tidak terinstal dengan benar. Pada macOS dan Windows, Docker Desktop adalah sumber utama credential helper. Jika instalasi Docker Desktop korup, di-update sebagian, atau komponen tambahannya gagal terinstal, credential helper bisa ada di PATH tapi binary-nya rusak sehingga mengembalikan exit status 1.

  4. pass (GNU Password Store) belum dikonfigurasi di Linux. Pada sebagian distribusi Linux, Docker dikonfigurasi menggunakan "credsStore": "pass". Namun pass membutuhkan GPG key yang sudah di-generate dan dikonfigurasi sebelumnya. Tanpa GPG key, docker-credential-pass akan gagal dengan error yang sama.

  5. Versi Docker atau credential helper yang tidak kompatibel. Jarang terjadi, tapi pernah dilaporkan ketika upgrade Docker Engine tanpa meng-upgrade Docker Desktop, atau sebaliknya, menyebabkan mismatch versi antara Docker daemon dan credential helper.

Cara memastikan penyebab mana yang kamu alami: Jalankan perintah berikut untuk mengecek apakah credential helper yang dikonfigurasi benar-benar ada dan bisa dieksekusi:

# Cek konfigurasi credsStore saat ini
cat ~/.docker/config.json | grep credsStore

# Coba panggil credential helper langsung
echo "https://index.docker.io/v1/" | docker-credential-desktop get

Jika perintah kedua mengembalikan command not found, berarti penyebabnya adalah nomor 1. Jika mengembalikan error not implemented atau error GPG, berarti penyebabnya nomor 3 atau 4. Jika konfigurasi credsStore mengacu pada helper yang bukan untuk OS kamu, berarti penyebabnya nomor 2.


Memperbaikinya Langkah demi Langkah

Langkah 1: Periksa konfigurasi Docker saat ini

Pertama, kamu perlu melihat apa yang tertulis di file konfigurasi Docker. Buka file tersebut:

cat ~/.docker/config.json

Output yang mungkin kamu lihat:

{
  "auths": {},
  "credsStore": "desktop"
}

Perhatikan nilai dari key credsStore. Ini adalah nama credential helper yang Docker coba panggil. Jika kamu tidak menggunakan Docker Desktop atau helper ini tidak tersedia di sistem kamu, inilah akar masalahnya.

Langkah 2: Hapus atau ubah konfigurasi credsStore

Solusi paling langsung adalah mengubah credsStore menjadi string kosong atau menghapus key tersebut seluruhnya, sehingga Docker akan menyimpan kredensial di file config.json secara base64-encoded (metode bawaan tanpa external helper).

# Edit file konfigurasi
nano ~/.docker/config.json

Ubah menjadi:

{
  "auths": {},
  "credsStore": ""
}

Atau, jika kamu ingin benar-benar menghapus key credsStore:

{
  "auths": {}
}

Simpan file tersebut.

Langkah 3: Coba login kembali

docker login

Output yang diharapkan:

Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: yourusername
Password: 
Login Succeeded

Jika kamu melihat Login Succeeded, maka masalah sudah terpecahkan.

Langkah 4: Verifikasi kredensial tersimpan

Cek bahwa kredensial benar-benar tersimpan di config.json:

cat ~/.docker/config.json

Output yang diharapkan menunjukkan entry di bawah auths:

{
  "auths": {
    "https://index.docker.io/v1/": {
      "auth": "YmFzZTY0X2VuY29kZWRfc3RyaW5n=="
    }
  },
  "credsStore": ""
}

Keberadaan key auth dengan nilai base64-encoded menandakan bahwa kredensial berhasil disimpan tanpa credential helper eksternal.

Langkah 5 (alternatif): Instal credential helper yang sesuai

Jika kamu lebih memilih menggunakan credential helper (yang lebih aman karena tidak menyimpan password dalam base64 yang mudah di-decode), instal helper yang sesuai dengan OS kamu:

Linux:

# Instal pass dan konfigurasi GPG
sudo apt-get install pass

# Generate GPG key jika belum ada
gpg --gen-key

# Inisialisasi password store
pass init "email@kamu.com"

# Update config.json
# Ubah credsStore menjadi "pass"

macOS (dengan Docker Desktop): Seharusnya docker-credential-osxkeychain sudah terinstal bersama Docker Desktop. Jika tidak:

# Reinstal Docker Desktop atau pastikan /Applications/Docker.app/Contents/Resources/bin ada di PATH

Windows: docker-credential-wincred seharusnya sudah tersedia melalui Docker Desktop.


Solusi Jangka Panjang

Mengosongkan credsStore memang menyelesaikan masalah, tapi itu bukan fix permanen yang paling baik dari sisi keamanan, karena password disimpan dalam base64 di file plain text. Berikut adalah konfigurasi permanen yang mencegah error kembali sambil menjaga keamanan kredensial.

Konfigurasi permanen per OS

Linux — Gunakan pass sebagai credential store:

# 1. Instal dependensi
sudo apt-get install pass gnupg2

# 2. Generate GPG key (jika belum ada)
gpg --full-generate-key
# Pilih RSA and RSA, ukuran 4096, dan masukkan informasi kamu

# 3. List GPG key yang baru dibuat
gpg --list-keys
# Catat ID key (hex string setelah pub rsa4096/)

# 4. Inisialisasi pass store
pass init "GPG_KEY_ID"

# 5. Konfigurasi Docker
mkdir -p ~/.docker
cat > ~/.docker/config.json << 'EOF'
{
  "auths": {},
  "credsStore": "pass"
}
EOF

# 6. Login
docker login

macOS — Gunakan osxkeychain:

{
  "auths": {},
  "credsStore": "osxkeychain"
}

Docker Desktop di macOS seharusnya sudah mengatur ini secara otomatis. Jika tidak, pastikan Docker Desktop terinstal dengan benar dan docker-credential-osxkeychain ada di PATH:

which docker-credential-osxkeychain

Jika tidak ditemukan, reinstal Docker Desktop.

Windows — Gunakan wincred:

{
  "auths": {},
  "credsStore": "wincred"
}

Sama seperti macOS, Docker Desktop untuk Windows seharusnya sudah mengatur ini. Verifikasi:

where.exe docker-credential-wincred

Best Practice

  • Jangan pernah meng-copy config.json antar mesin atau OS yang berbeda. Ini adalah sumber error yang paling sering terjadi. File konfigurasi Docker mengandung referensi ke credential store yang spesifik per OS. Copy antar OS akan menyebabkan mismatch.
  • Gunakan credential helper daripada base64 auth. Meskipun mengosongkan credsStore lebih mudah, menyimpan password dalam base64 di plain text adalah risiko keamanan. Siapa pun yang bisa membaca ~/.docker/config.json bisa mendecode kredensial kamu dengan echo "YmFzZTY0..." | base64 -d.
  • Gunakan token daripada password. Docker Hub mendukung Personal Access Token (PAT) yang bisa di-batasi scope-nya dan di-revoke kapan saja tanpa mengubah password akun. Buat token di https://hub.docker.com/settings/security, lalu gunakan token sebagai password saat docker login.
  • Set permission file konfigurasi dengan benar:
chmod 600 ~/.docker/config.json

Ini memastikan hanya user kamu yang bisa membaca file tersebut.

  • Jika menggunakan CI/CD, gunakan --password-stdin agar password tidak tertinggal di shell history:
echo "$DOCKER_TOKEN" | docker login -u "$DOCKER_USER" --password-stdin

Perbedaan antar OS