Questo rapporto viene riverificato man mano che il mirror di ANAC si completa: i controlli di integrità sono stati fatti su cinque file, e verranno ripetuti su tutte le 1.797 risorse. Ogni correzione è registrata in fondo, nel registro delle revisioni.
Rilevazione del 26 ottobre 2026 · Osservatorio Nazionale Sovranità Digitale · progetto analisi-spesa-ict
Questo rapporto descrive i problemi di disponibilità e di integrità che abbiamo misurato sui
dati aperti della Banca Dati Nazionale dei Contratti Pubblici, pubblicati da ANAC su
dati.anticorruzione.it. È scritto per essere presentato ad ANAC: ogni numero è riproducibile a
partire dai file indicati in appendice, con il loro sha256, e dallo script pubblicato.
Non è un giudizio sul lavoro di ANAC, che pubblica uno dei patrimoni di dati sugli appalti più ampi d’Europa. È l’elenco delle cose che, se corrette, renderebbero quel patrimonio pienamente riutilizzabile.
Sintesi
Cosa funziona bene. Il CIG è un identificativo eccellente: su oltre 4,8 milioni di CIG distinti controllati con l’algoritmo pubblicato da ANAC, quelli non validi sono diciassette. I dataset tabellari escono con regolarità il secondo giorno del mese. La licenza è dichiarata. L’API CKAN funziona.
I problemi, in ordine di impatto per chi riusa i dati:
- Il canale OCDS è inservibile. Non solo è fermo a marzo 2026: mesi diversi servono lo stesso file, con il solo indirizzo riscritto. Dei 23 mesi che rispondono 200 i contenuti distinti sono al massimo 11, e sei mesi consecutivi condividono un unico file da 3,18 GB. Chi ne ricava una serie storica conta più volte gli stessi dati. I file mancanti rispondono 404 senza alcun avviso sul portale.
- I file storici spariscono, e la regola non è scritta da nessuna parte. I delta di gennaio,
febbraio e marzo 2026 non sono più scaricabili. Il file annuale del 2026 non esiste: chi non ha
scaricato ogni mese ha perso quei mesi, e potrà recuperarli solo quando uscirà l’annuale.
Ci sono buchi anche dentro la finestra disponibile: di
smartcigmancano giugno e luglio 2026, mentre i mesi prima e dopo ci sono. - I file “completi” sono istantanee di gennaio.
aggiudicazionieaggiudicatarihanno data di ultima modifica 15 e 23 gennaio 2026: lo stato corrente si ricostruisce solo applicando i delta. - L’accesso automatico è ostacolato. Il portale respinge gli user-agent che non sembrano
browser, anche sui dati aperti, rispondendo 200 con una pagina HTML al posto del file. Altri
progetti riferiscono anche un blocco degli IP dei servizi cloud, che non abbiamo verificato.
L’API REST OCDS documentata risponde 404; l’API CKAN che funziona non è documentata. Nessuna
risorsa espone
ETag, e la dimensione dichiarata nel catalogo è quella del file scompattato, circa 4,1 volte quella servita. - Campi codificati che accettano testo libero. Nel dataset
cup, 1.951.844 righe — il 27% — hanno come CUP la stringaND: dichiarano un collegamento fra CIG e CUP per dire che il CUP non c’è. - Incongruenze fra dataset collegati. 10.812 aggiudicazioni con importo positivo non hanno alcun
aggiudicatario; 3.424 aggiudicatari rimandano a un’aggiudicazione che non esiste; 6.874 chiavi
(cig, id_aggiudicazione)sono ripetute. - Convenzioni non documentate che rompono i collegamenti con le altre basi dati pubbliche: codici
fiscali sintetici
CFAVCP-…per 1.282 stazioni appaltanti, partita IVA00000000000per metà delle stazioni appaltanti, data di fine2099per tutte. - Nessun campo per gli operatori esteri. Gli identificativi fiscali stranieri finiscono nel campo
codice_fiscalein formati eterogenei, senza indicazione del paese.
In fondo al rapporto, dodici richieste concrete, e una tabella che documenta i mesi duplicati.
1. Metodo
- File analizzati: cinque risorse scaricate il 26 ottobre 2026 dal portale, conservate in un
archivio append-only con il loro
sha256(tabella in appendice). - Strumenti: DuckDB per i conteggi, Python per le validazioni. Il CIG è validato con l’algoritmo
pubblicato da ANAC nel repository
anticorruzione/npa, nell’implementazione diaborruso/anac-pl-pp-cli. Codici fiscali e partite IVA con i rispettivi caratteri di controllo. - Script:
tools/anac_integrita.py. Rilanciato sugli stessi file, produce gli stessi numeri. - Sonda di disponibilità: 125 risorse interrogate il 26 ottobre 2026 con
tools/sonda.py; esiti e intestazioni HTTP instato/sonda/2026-10-26.jsonl. - Riscontro indipendente: gli
sha256diaggiudicazioni_csv.zipeaggiudicatari_csv.zipcoincidono con quelli registrati a settembre, in modo indipendente, dal progetto DoveVannoINostriSoldi. Due misure separate, lo stesso file. - Cautela: un conteggio anomalo non è sempre un errore. Dove un valore può essere legittimo lo diciamo, e lo classifichiamo come convenzione o come incongruenza da chiarire, non come errore.
2. Disponibilità e accesso
| # | Problema | Prova | Impatto |
|---|---|---|---|
| D1 | OCDS fermo a marzo 2026 | GET …/ocds/filesystem/bulk/2026/04.json → 404, e così fino a 09.json; 03.json → 200 | Nessuna serie OCDS dopo marzo. Chi usa lo standard internazionale — fra cui gli strumenti di Open Contracting Partnership — si ferma lì |
| D2 | Delta storici scomparsi | 20260101-, 20260201-, 20260301-cig_csv.zip → 404; 20260401- … 20261001- → 200 | Tre mesi del 2026 irrecuperabili fino al file annuale |
| D3 | Politica di conservazione non dichiarata | A settembre erano in linea sei delta, a ottobre sette: non è una finestra a sei mesi, e la regola non è deducibile | Nessun riutilizzatore può pianificare l’archiviazione |
| D4 | File annuale dell’anno in corso assente | package_show?id=cig-2026 → dataset inesistente | Tutto il 2026 vive solo nei delta |
| D5 | File “completi” fermi a gennaio | Last-Modified di aggiudicazioni_csv.zip 15/01/2026, di aggiudicatari_csv.zip 23/01/2026 | Lo stato corrente richiede di applicare tutti i delta, che però spariscono (D2) |
| D6 | Rifiuto degli user-agent non-browser | Con user-agent python-requests o curl il server risponde 200 con una pagina HTML al posto del file; con user-agent da browser serve lo zip. Altri progetti riferiscono anche un blocco degli IP cloud, non verificato da noi | Gli strumenti automatici devono girare su macchine dedicate o simulare un browser |
| D7 | API REST OCDS dichiarata ma non funzionante | Tutti gli endpoint su api.anticorruzione.it/opendata/ocds/api/v1/… → 404; swagger.json non è JSON valido | Chi segue la documentazione ufficiale non ottiene nulla |
| D8 | API CKAN funzionante ma non documentata | …/opendata/api/3/action/package_show?id=cig → 200 | È il modo migliore di accedere ai dati, e nessuno sa che c’è |
| D9 | ETag assente su tutte le risorse | Verificato su 95 risorse ANAC sondate: nessuna lo espone. Consip, SIOPE e il Dipartimento per la Trasformazione Digitale lo espongono | Per sapere se un file è cambiato bisogna riscaricarlo per intero |
| D10 | Buchi nella pubblicazione dei delta, dentro la finestra disponibile | smartcig 2026-06 e 2026-07 → 404 sia in CSV sia in JSON, mentre 04, 05, 08, 09 e 10 sono presenti. Il catalogo CKAN non li elenca affatto | Due mesi di affidamenti sotto soglia non sono mai stati pubblicati, o sono stati rimossi. Non sono recuperabili dal file annuale, che per il 2026 non esiste |
| D11 | Il 2026 dell’OCDS contiene solo marzo, e marzo contiene solo marzo | bulk/2026/01.json e 02.json → 404, 03.json → 200, da 04 a 10 → 404. Il file di marzo, letto integralmente, contiene 127.401 release datate 2026-03 e 1.139 datate 2026-04: nessuna di gennaio o febbraio | Un unico mese pubblicato in tutto l’anno, e i due mesi mancanti non sono recuperabili da quello presente |
| D14 | Mesi diversi dell’OCDS servono lo stesso file, con il solo uri riscritto | Vedi la tabella al §4: i gruppi di mesi hanno Content-Length identico al byte e blocchi di 64 KB identici a offset di 1, 2 e 3 GB. Fra 2025/01.json e 2025/04.json l’unica differenza nei primi 1.200 byte è il campo uri, che riecheggia il percorso richiesto | È il problema più grave del canale OCDS. Dei 23 mesi che rispondono 200, i contenuti distinti sono al massimo 11. Chi costruisce una serie storica mese per mese conta più volte gli stessi dati senza accorgersene |
| D15 | Release senza data utilizzabile | Nel file di marzo 2026, 19.829 release su 148.369 (13,4%) non hanno un campo date interpretabile | Non sono collocabili nel tempo |
| D17 | Il catalogo elenca risorse che non esistono | Censite 1.801 risorse dei 70 dataset: 4 sono elencate ma rispondono 404, fra cui ocds-appalti-ordinari-2025/…_2025_12, …_2026_01 e …_2026_02 | Chi si fida del catalogo pianifica scarichi che falliranno. Sono gli stessi mesi OCDS mancanti del §4: il catalogo li annuncia, il server non li ha |
| D18 | Lo scarto fra dimensione dichiarata e servita è sistematico | Su tutte le 1.797 risorse scaricabili: il catalogo dichiara 524,78 GB, il server ne serve 128,92 GB. Sovrastima media 4,1 volte, con punte di 14 volte su cig-2011 | Rende impossibile pianificare spazio e banda, e verificare un download |
| D16 | Date di aggiudicazione impossibili | Nello stesso file, 105 aggiudicazioni su 116.871 hanno data successiva a ottobre 2026, fra cui 2205-12 e 2926-03 | Stesso difetto già visto nei tabellari: nessun controllo di plausibilità sulle date |
| D12 | La distribuzione JSON di smartcig si è interrotta | 20260801, 20260901 e 20261001-smartcig_json.zip → 404, mentre i corrispondenti _csv.zip → 200 | Chi consuma il formato JSON si ferma a maggio 2026, senza alcun avviso |
| D13 | La dimensione dichiarata nel catalogo non è quella del file servito | Per cig_csv_2025_01.zip CKAN dichiara 91.942.157 byte, il server ne serve 20.798.988. Per 20261001-cig_csv.zip dichiara 482.505.250 byte contro 107.879.691 serviti, e 482.505.250 è esattamente la dimensione del CSV contenuto in quello zip. Vedi anche D18 per la misura su tutte le risorse | Il campo size descrive il contenuto scompattato invece della distribuzione. Chi pianifica lo spazio o verifica un download sbaglia di circa 4,5 volte |
4. I mesi duplicati del canale OCDS
Tutti i mesi che rispondono 200, con la dimensione servita e il gruppo di appartenenza. I mesi
nello stesso gruppo servono lo stesso contenuto: dimensione identica al byte e blocchi
identici a offset di 1, 2 e 3 GB, con il solo uri riscritto.
| Gruppo | Mesi che servono lo stesso file | Byte |
|---|---|---|
| A | 2024/01, 2024/02 | 669 MB |
| B | 2024/03 | 636 MB |
| C | 2024/04 | 1.511 MB |
| D | 2024/05, 2024/06, 2024/07 | 1.516 MB |
| E | 2024/08 | 1.132 MB |
| F | 2024/09 | 1.485 MB |
| G | 2024/10 | 1.881 MB |
| H | 2024/11, 2024/12, 2025/01, 2025/02, 2025/03, 2025/04 | 3.183.014.151 |
| I | 2025/05, 2025/06, 2025/07, 2025/08, 2025/09 | 3.156.244.395 |
| L | 2025/10, 2025/11 | 5.003 MB |
| M | 2026/03 | 748.374.251 |
Mancano del tutto: 2025/12 e tutti i mesi del 2026 tranne marzo.
Verificati direttamente: A, D, H (su tre coppie), I e L. I gruppi B, C, E, F, G e M hanno dimensione unica e sono quindi file distinti.
Tutti i file dei gruppi da A a M portano publishedDate 8 o 9 aprile 2026: sono stati rigenerati
in un’unica sessione, a ritroso nel tempo, nell’arco di circa un giorno.
Questo spiega un episodio pubblico: la piattaforma commerciale AppaltIntel ha ritirato un’analisi in cui attribuiva al mercato un calo dei bandi del 2023, scoprendo poi che il calo veniva dalla fonte. La loro documentazione tecnica parla di mesi per cui «all’indirizzo del mese mancante rispondeva il file di un altro mese». Quanto sopra è la verifica di quel fenomeno, a livello di byte.
3. Integrità
3.1 Errori
Valori incompatibili con la definizione del campo, o fra loro.
| ID | Problema | Casi | Su | |
|---|---|---|---|---|
| AT-05 | Aggiudicazione con importo positivo e nessun aggiudicatario | 10.812 | 4.809.518 aggiudicazioni | 0,22% |
| AT-04 | Aggiudicatario che rimanda a un’aggiudicazione inesistente | 3.424 | 4.822.171 coppie | 0,07% |
| AG-01 | Chiave (cig, id_aggiudicazione) ripetuta | 6.874 | 4.862.077 righe | 0,14% |
| AG-10 | Ribasso fuori dall’intervallo 0-100 | 16.123 | 4.862.077 | 0,33% |
| AG-11 | Più offerte ammesse che imprese offerenti | 12.012 | 4.862.077 | 0,25% |
| AG-07 | Importo di aggiudicazione negativo | 368 | 4.862.077 | 0,01% |
| AG-03c | Data di aggiudicazione definitiva nel futuro | 768 | 4.862.077 | 0,02% |
| AG-04c | Data di comunicazione dell’esito nel futuro | 163 | 4.862.077 | <0,01% |
| AG-03b | Data di aggiudicazione definitiva anteriore al 2000 | 1.138 | 4.862.077 | 0,02% |
| AG-12 | Esito “vincitore non ancora selezionato” ma con data e importo di aggiudicazione | 153 | 4.862.077 | <0,01% |
| AT-01a | Codice fiscale o partita IVA italiani con carattere di controllo errato | 8.016 | 527.722 identificativi distinti | 1,52% |
| CD-03 | Importo del lotto nullo o negativo (delta di ottobre) | 377 | 565.864 | 0,07% |
| AG-02 · AT-03 · CU-01 · CD-01 | CIG non valido | 17 · 16 · 13 · 3 | milioni | ≈0% |
3.2 Incongruenze da chiarire
Possono avere una spiegazione procedurale, ma chi riusa i dati non ha modo di saperlo.
| ID | Problema | Casi | |
|---|---|---|---|
| AG-05 | Esito comunicato prima dell’aggiudicazione definitiva | 225.914 | 4,6% |
| AG-08 | Importo di aggiudicazione pari a zero | 19.067 | 0,39% |
| AG-09 | Importo pari o superiore a un miliardo di euro | 298 | da verificare uno per uno |
| AG-03d | Data di aggiudicazione definitiva mancante | 42.479 | 0,87% |
3.3 Campi codificati che accettano testo libero
Il problema non sono i singoli valori, ma l’assenza di validazione all’inserimento.
Il CUP nel dataset cup. Su 7.228.216 righe, 1.955.119 non contengono un CUP ben formato:
| Contenuto del campo | Righe |
|---|---|
ND | 1.951.844 |
| altro testo libero o codice malformato | 2.013 |
| CUP valido ma con spazi o minuscole | 942 |
NON APPLICABILE | 632 |
più CUP o note nello stesso campo, per esempio I53D23002750001 € 454,55 I53D23002620006 € 277,27 | 80 |
Conseguenza pratica: dei 7.103.635 CIG presenti nel dataset, quelli con almeno un CUP valido sono 5.149.498, il 72,5%. Chi conta le righe sovrastima i collegamenti di un quarto.
Gli identificativi degli aggiudicatari. 2.012 campi codice_fiscale contengono più identificativi
o annotazioni, per esempio C.F. … - P. IVA ….
3.4 Convenzioni non documentate
Non sono errori, ma senza documentazione rompono i collegamenti con IndicePA, il Registro Imprese e le altre basi dati pubbliche.
| ID | Convenzione | Casi |
|---|---|---|
| SA-02 | Codici fiscali sintetici CFAVCP-… per stazioni appaltanti senza codice fiscale proprio, per lo più centrali uniche di committenza. 1.194 sono attive | 1.282 su 48.040 |
| SA-03 | Partita IVA 00000000000 al posto del valore mancante | 24.818 su 48.040 (51,7%) |
| SA-05 | Data di fine 2099-12-31 come “ancora attivo” | 48.040 su 48.040 |
| AG-13 | Criterio di aggiudicazione mancante | 3.226.120 su 4.862.077 (66,4%) |
| — | Due vocabolari coesistenti per lo stesso campo: PREZZO PIU' BASSO accanto a OFFERTA ECONOMICAMENTE PIÙ VANTAGGIOSA: CRITERIO DEL MINOR PREZZO; IMPRESA accanto a IMPRESA SINGOLA (…), DITTA INDIVIDUALE, MONOSOGGETTIVO | — |
3.5 Un’assenza di schema: gli operatori esteri
Il dataset aggiudicatari non ha un campo per il paese dell’operatore né per il tipo di
identificativo. Gli operatori stranieri finiscono quindi in codice_fiscale con formati eterogenei:
| Forma dell’identificativo | Distinti |
|---|---|
| Codice fiscale o partita IVA italiani validi | 483.510 (91,6%) |
Identificativo IVA con prefisso del paese, per esempio ATU…, IE… | 6.449 |
| 9-10 cifre: identificativi esteri o italiani troncati, non distinguibili | 10.214 |
Altri formati: identificativi nazionali esteri, per esempio G62060421 per la Spagna | 17.521 |
Per chi studia a quali paesi vanno gli appalti pubblici italiani — cioè per questo progetto, ma anche per qualunque analisi sul mercato unico europeo — è un’informazione essenziale, ed è oggi ricostruibile solo per euristica.
Richieste
In ordine di impatto per chi riusa i dati.
- Correggere il canale OCDS: far sì che ogni mese contenga il proprio mese, ripubblicare i mesi mancanti, e nel frattempo dichiarare sul portale che la distribuzione non è affidabile. In alternativa dichiararla sospesa con una data di ripresa.
- Non rimuovere i delta storici, oppure pubblicare un archivio permanente, e dichiarare la politica di conservazione.
- Pubblicare il file dell’anno in corso, aggiornato insieme ai delta, così che lo stato corrente non dipenda dall’aver scaricato ogni mese.
- Documentare l’API CKAN e dichiarare formalmente dismessa l’API REST OCDS, o ripristinarla.
- Esporre
ETage pubblicare i checksum di ogni risorsa. - Consentire l’accesso automatico ai dati aperti senza blocchi sugli IP cloud e sullo user-agent, eventualmente con un limite di frequenza dichiarato.
- Validare in inserimento i campi codificati: un CUP assente è un valore nullo, non
ND; un campo codice fiscale contiene un identificativo, non note. - Documentare le convenzioni — i codici
CFAVCP-…, la partita IVA00000000000, la data2099— e indicare per le centrali di committenza il codice fiscale degli enti aderenti. - Aggiungere paese e tipo di identificativo per gli operatori economici esteri.
- Correggere le chiavi duplicate e i riferimenti orfani fra
aggiudicazionieaggiudicatari. - Pubblicare i mesi mancanti di
smartcig, giugno e luglio 2026, e ripristinare la distribuzione JSON, interrotta da agosto 2026. - Correggere il campo
sizedel catalogo, perché descriva la distribuzione scaricabile e non il file scompattato.
Siamo disponibili a fornire gli elenchi completi dei record interessati da ciascun controllo e a ripetere la rilevazione dopo eventuali correzioni.
Appendice A — I file analizzati
Scaricati il 26 ottobre 2026 da https://dati.anticorruzione.it/opendata/download/dataset/.
| Risorsa | Byte | Last-Modified | sha256 |
|---|---|---|---|
stazioni-appaltanti/filesystem/stazioni-appaltanti_csv.zip | 3.131.101 | 13/10/2026 | fa27841b2379bb07cd1dfcab334ea85e4bc92472571a93dca4db450efb8804f8 |
cup/filesystem/cup_csv.zip | 82.859.488 | 13/10/2026 | d83b0d42e6574eed3c26de59d6ffc124c0ce4756b5d34013e7bbe31daafb39cb |
aggiudicazioni/filesystem/aggiudicazioni_csv.zip | 151.402.917 | 15/01/2026 | 70f2e7ccad625f3db3d3a2285c65aaa8eac35bf70b25570774224ac869f8d631 |
aggiudicatari/filesystem/aggiudicatari_csv.zip | 151.222.321 | 23/01/2026 | 6908a361f581824ce144414116301234fc113230230634b0942b988f9173d60f |
cig/filesystem/20261001-cig_csv.zip | 107.879.691 | 05/10/2026 | 204f820f5222f6c975c45998b2bd8f69bec0ca90a4cbeea55e7a25ec09c0924a |
Appendice B — Tutti i controlli
L’elenco completo, con esempi, sta in integrita-2026-10-26.json.
Registro delle revisioni
| Versione | Data | Cosa è cambiato |
|---|---|---|
| 1.0 | 26/10/2026 | Prima pubblicazione: 18 problemi di disponibilità, 33 controlli di integrità, 12 richieste |
| 1.1 | 26/10/2026 | Corretto il problema D6. Avevamo scritto che ANAC blocca gli IP dei servizi cloud: l’abbiamo verificato solo per gli user-agent non-browser, a cui il server risponde 200 con una pagina HTML al posto del file. Il blocco degli IP cloud è riferito da altri progetti e resta da verificare. Dato sulla sovrastima delle dimensioni allineato a 4,1 volte, misurato su tutte le risorse |
Verifiche in corso
| Cosa | Stato |
|---|---|
| Controlli di integrità ripetuti su tutte le risorse del mirror, non solo sui cinque file iniziali | in attesa del mirror completo |
| Deduplicazione dell’OCDS misurata sui file archiviati: quanti GB sono contenuti ripetuti | in attesa del mirror completo |
| Confronto fra CSV, JSON e TTL della stessa risorsa: stessi record? | da fare |
| Ripetizione mensile della sonda: i problemi aperti vengono risolti? | da fare |