Column name cut to 10 characters (and what to do about it)
Short answer: a Shapefile's attribute table is a dBase file, and the dBase header stores each field name in 11 bytes, one of which is a terminator — 10 characters is the ceiling. GDAL warns once at export and cuts the name; every reader afterwards sees the short one, because the long one was never written. Since GDAL 3.13 a .shp.xml sidecar can bring it back, but only when the sidecar lists every field, in order — and the browser viewer reads no sidecar at all. The fix is to choose the abbreviations yourself before exporting, or to leave the format.
Everything below was tested on 16 September 2026 with GDAL 3.13.3 and the live shapefile-viewer at static-page-tools@442f8d8; what each tool printed is quoted. The dataset is IBGE's 2022 mesh of the 27 Brazilian states, whose five fields — CD_UF, NM_UF, SIGLA_UF, NM_REGIAO, AREA_KM2 — are all nine characters or shorter, so every truncation here is induced with a -sql alias. The Shapefile guide explains the limit under "Field names are cut at 10 characters"; this post is the reproduction, in GDAL and in the browser, and the fix.
The warning, verbatim
Exporting the mesh with a 26-character alias, ogr2ogr -f "ESRI Shapefile" long/long.shp uf.gpkg -sql "SELECT *, NM_UF AS nome_da_unidade_federativa FROM BR_UF_2022", prints one line: Warning 6: Normalized/laundered field name: 'nome_da_unidade_federativa' to 'nome_da_un'. ogrinfo -so long/long.shp long then lists six fields, the last of them nome_da_un: String (50.0) — the width came from NM_UF, the name was cut at ten. The control: the same pipeline with an alias of exactly ten characters, NM_UF AS nome_da_un, exits 0 with no warning and stores the name as given. It is the length, nothing else.
Collisions: nome_da_un, nome_da__1, nome_da__2
Three long names that share their first ten characters, exported together (NM_UF AS nome_da_unidade_federativa, NM_REGIAO AS nome_da_unidade_regional, SIGLA_UF AS nome_da_unidade_sigla), draw three warnings and three different short names:
nome_da_unidade_federativabecamenome_da_un— the first ten characters, as in the single case.nome_da_unidade_regionalbecamenome_da__1— the first eight characters plus_1; the double underscore is there because the eighth character of the prefix is already_.nome_da_unidade_siglabecamenome_da__2— the same rule, next counter.
The widths follow the source column, not the alias: nome_da__1 is String (20.0) from NM_REGIAO, nome_da__2 is String (2.0) from SIGLA_UF. Whoever opens this file next month sees nome_da__2 and has no way to learn it was the state abbreviation. The guide's observat_1 is the same rule on a different dataset.
The .shp.xml sidecar: GDAL 3.13 restores the name, with conditions
The guide says GDAL 3.13 and later reads .shp.xml to restore field names longer than 10 characters and their aliases. We tested it on 3.13.3, and it stands — with two conditions a naive test will miss.
The sidecar is the ArcGIS metadata file, <basename>.shp.xml; the reader walks its <attr> elements in order, pairing the n-th <attr> with the n-th .dbf field. With a hand-written long.shp.xml listing all six fields in DBF order, the sixth carrying <attrlabl>nome_da_unidade_federativa</attrlabl> and <attalias>Nome da UF</attalias>, ogrinfo -al -so long/long.shp prints nome_da_unidade_federativa: String (50.0), alternative name="Nome da UF". The 26-character name is the field name, not a display alias: ogr2ogr -f GPKG alias.gpkg long/long.shp produces a GeoPackage whose column is nome_da_unidade_federativa, with Nome da UF riding along as the alternative name. The .dbf was byte-identical before and after; the sidecar alone made the difference.
The conditions: every field must be listed, and in DBF order. A sidecar with a single <attr> for the long field — our negative control — is discarded and the layer still reads nome_da_un; and it is discarded silently, because the fewer-fields path in the reader prints nothing even under ogrinfo --debug on. Two other rejections do speak: a seventh <attr> prints More fields in .shp.xml than in .dbf, and a long label whose first five characters differ from a ten-character .dbf name prints For field at index 5, mismatch between .shp.xml name (unidade_federativa_nome) vs .dbf name (nome_da_un) (the check is skipped when the .dbf name is shorter than ten characters — a short field mislabelled with a long name is discarded as silently as the partial sidecar). There is no switch — ogrinfo --format 'ESRI Shapefile' lists no option for it; the file is read whenever it is there. The reader is built for the metadata file ArcGIS writes, which is where those aliases come from; a GDAL export writes none (ls long/ → .dbf .prj .shp .shx).
What the browser viewer shows
Drop the laundered file into the shapefile-viewer as a zip — .shp, .shx, .dbf, .prj and even the complete .shp.xml inside — and the layers panel reads 27 polygons and 6 fields; the attribute table's header, after Row number and Type, is CD_UF, NM_UF, SIGLA_UF, NM_REGIAO, AREA_KM2, nome_da_un. The first row's nome_da_un cell reads Acre, the same value as its NM_UF: the data came through, only the name was cut. The viewer's parser, shpjs, never opens a sidecar (grep -c 'shp.xml' node_modules/shpjs/lib/index.js → 0), so the header shows what the .dbf says, whatever the .shp.xml beside it says. The Portuguese and Spanish versions of the tool show the same header: column names are your keys, verbatim, in every language.
When to leave Shapefile
The same alias written to the other two formats keeps its name: ogr2ogr -f GPKG gives nome_da_unidade_federativa: String (50.0), and ogr2ogr -f GeoJSON gives "nome_da_unidade_federativa":"Acre" as a property key on each of the 27 states, with nome_da_un nowhere in the file. The comparison post measured the three formats side by side under "Field names"; the GeoPackage guide is where to start if the team can move.
The closing fact is the round trip. Converting the laundered Shapefile back with ogr2ogr -f GPKG back.gpkg long/long.shp — no sidecar beside it — gives a GeoPackage whose field is still nome_da_un, and grep -c 'nome_da_unidade_federativa' back.gpkg returns 0. The name is not hidden somewhere in the file; it was never written, and no later conversion can invent it. If you must deliver a Shapefile, rename the fields to ten characters or fewer before exporting so that you choose the abbreviations, keep the GeoPackage as the master copy, and treat the Shapefile as a lossy export.
Test files you can use
The dataset is IBGE's 2022 state mesh, 13,717,460 bytes, SHA-256 282ec7f0f0beeeead45e6609f4ffffce161bda04cb8ee0afcad2316d1c841bcb; the directory listing prints no licence line, so credit IBGE and check the portal's terms before republishing.
To make the broken variant, convert once to GeoPackage (ogr2ogr -f GPKG uf.gpkg BR_UF_2022.shp) and export with the alias: ogr2ogr -f "ESRI Shapefile" long/long.shp uf.gpkg -sql "SELECT *, NM_UF AS nome_da_unidade_federativa FROM BR_UF_2022". Zip the four files and drop them into the viewer.
For teams
A field name cut to ten characters is a small thing until the form built on it has twenty of them and nobody remembers what nome_da__2 was. Geodocs keeps the field names your team wrote, with their accents, on a shared map where the data is collected and reviewed; the Shapefile question only comes up at export, when you already know which ten characters to keep.