tar: Cannot change ownership to uid: Invalid argument

Subes un proyecto desde Git Bash (Windows) a un servidor Linux empaquetándolo con tar y enviándolo por SSH:

tar cf - . | ssh usuario@servidor "tar xf - -C /destino"

La transferencia termina, pero el tar del servidor imprime una avalancha de líneas como estas:

tar: ./archivo: Cannot change ownership to uid 197610, gid 197121: Invalid argument
tar: ./otro-archivo: Cannot change ownership to uid 197610, gid 197121: Operation not permitted
tar: Exiting with failure status due to previous errors

Este artículo explica de dónde salen esos números, por qué el servidor intenta usarlos y cómo evitar el error. Los pasos de creación y listado del archivo se reprodujeron con GNU tar 1.35 de Git Bash en un directorio temporal; el error en sí ocurre en el servidor y no se reprodujo (no se usó ningún servidor), así que esa parte se apoya en el manual de GNU tar y en la documentación de Linux.

Por qué pasa

Un archivo tar guarda, para cada entrada, el propietario y el grupo del archivo original. Puedes verlo con tar tvf:

tar tvf proyecto.tar
tar --numeric-owner -tvf proyecto.tar
-rw-r--r-- usuario/197121     18 2026-01-15 10:30 ./package.json
-rw-r--r-- 197610/197121      18 2026-01-15 10:30 ./package.json

(Salida de ejemplo: la primera línea es el listado normal, con el nombre del propietario y el número de grupo; la segunda, el de --numeric-owner, con números.) En Git Bash tu cuenta de Windows se presenta con un uid y un gid numéricos altos; en la prueba, id -u devolvió un número de seis cifras. Esos números no corresponden a ninguna cuenta del servidor.

Al extraer, el manual de GNU tar indica que --same-owner (intentar extraer con el mismo propietario que figura en el archivo) es el comportamiento por defecto del superusuario, mientras que --no-same-owner (extraer como tú mismo) es el de los usuarios normales. Por eso el problema aparece cuando extraes como root: tar intenta ejecutar un chown a un uid y un gid que el servidor no conoce o no puede asignar.

Los dos mensajes del error indican cosas distintas:

  • Operation not permitted: el proceso no tiene privilegio para cambiar el propietario. Según chown(2), solo un proceso privilegiado (en Linux, con la capacidad CAP_CHOWN) puede cambiar el propietario de un archivo.
  • Invalid argument: el sistema rechaza el número como propietario. Suele verse cuando el destino no puede representar ese id, por ejemplo en un contenedor o un espacio de nombres de usuario con un rango limitado: user_namespaces(7) explica que cada espacio de nombres solo conoce los ids que tiene asignados y que los demás se tratan como no asignados.

El error no dice que el archivo esté dañado, solo que no se pudo asignar el propietario. Pero tar termina con estado de fallo (el manual define el código 2 como error fatal), lo que puede cortar un script que encadene comandos con && o use set -e.

Solución

  1. Extrae sin conservar el propietario del archivo. Añade --no-same-owner al tar del servidor:

    tar cf - . | ssh usuario@servidor "mkdir -p /destino && tar xf - --no-same-owner -C /destino"

    Los archivos quedan a nombre del usuario que ejecuta la extracción. Si la aplicación corre con otra cuenta, ajusta después el propietario con chown -R cuenta:grupo /destino.

  2. Alternativa: crea el archivo con propietario neutro. Con --owner, --group y --numeric-owner el archivo registra el uid 0 y el gid 0 en lugar de los de Windows:

    tar --owner=0 --group=0 --numeric-owner -cf - . | ssh usuario@servidor "mkdir -p /destino && tar xf - -C /destino"

    En la prueba, el listado con tar tvf mostró 0/0 en todas las entradas. Si el servidor extrae como root, los archivos quedarán a nombre de root; si lo hace un usuario normal, a nombre de ese usuario. Elige esta opción cuando quieras que el archivo sea portable y no solo arreglar el servidor.

  3. Si también molestan los permisos, añade --no-same-permissions.

    tar xf - --no-same-owner --no-same-permissions -C /destino

    Según el manual, preservar los permisos del archivo es lo habitual para el superusuario; --no-same-permissions hace que se aplique la umask del usuario que extrae. Úsalo solo si lo necesitas: puede quitar bits que quieras conservar (por ejemplo, el de ejecución de un script). Revisa después con ls -l.

  4. Comprueba que no falte ni cambie nada. Genera una lista de sumas de verificación fuera de la carpeta del proyecto, envíala al servidor y compárala:

    find . -type f -exec sha256sum {} + > ../manifiesto.sha256
    scp ../manifiesto.sha256 usuario@servidor:/tmp/manifiesto.sha256
    ssh usuario@servidor "cd /destino && sha256sum -c /tmp/manifiesto.sha256"

    Cada archivo debe mostrar OK. No guardes el manifiesto dentro del proyecto (por eso va en ..): así no se incluye a sí mismo en la lista ni en el envío.

Cómo verificar que quedó resuelto

Ejecuta de nuevo el comando de la solución y comprueba tres cosas:

echo "${PIPESTATUS[@]}"
ssh usuario@servidor "ls -ln /destino | head"

El primer comando se ejecuta en Git Bash justo después de la tubería y debe mostrar 0 0: el primer valor es el de tar local y el segundo el de ssh, que según su manual termina con el estado del comando remoto. El segundo comando muestra los propietarios numéricos: deben ser ids que existan en el servidor, no el de Windows. Por último, sha256sum -c debe dar OK en todos los archivos.

Variantes y errores relacionados

Solo fallan algunos archivos con Operation not permitted

Es la misma causa: tar intentó cambiar el propietario sin el privilegio necesario. La solución es la misma, --no-same-owner, en lugar de dar más privilegios al proceso.

En PowerShell, tar no es GNU tar

Las opciones de este artículo son de GNU tar (Git Bash y el servidor Linux). En una consola de PowerShell, tar suele ser el bsdtar que trae Windows (tar --version muestra bsdtar y la versión de libarchive), con opciones distintas; la ayuda que imprime no lista --owner ni --group. Ejecuta el comando de creación desde Git Bash.

El error sale en un contenedor o en un disco montado

Si extraes dentro de un contenedor o sobre un sistema de archivos que no admite propietarios arbitrarios, --no-same-owner también es la salida. Si de verdad necesitas conservar los propietarios, el servidor debe tener esos ids disponibles, y ese ya es un asunto de la configuración del contenedor o del montaje.

Resumen

  • El archivo de Git Bash guarda uid y gid numéricos altos de tu cuenta de Windows; el servidor no los conoce.
  • Como root, GNU tar conserva por defecto el propietario del archivo (--same-owner), y el chown falla con Invalid argument o Operation not permitted.
  • La solución directa es extraer con tar xf - --no-same-owner -C /destino.
  • También puedes crear el archivo con --owner=0 --group=0 --numeric-owner para que no lleve ids de Windows.
  • Aunque el error sea solo de propietarios, comprueba el resultado con sha256sum -c y revisa el estado de salida.

Referencias

Comentarios