
A GSTR-1 upload fails in a particular way. The file opens in the offline tool, the figures it shows are the figures you expect, and the portal still refuses it, usually with a message that names a row number and nothing else.
The reason is that the JSON is not read as a spreadsheet. It is validated against a schema GSTN publishes, and that schema is strict in places nobody would guess: one key it does not recognise is a hard refusal of the whole file, not a warning on one line.
This is what that schema actually says, and the four things that most often break a file that looks correct.
The file is a schema, not a spreadsheet
GSTN publishes the request schema for "GSTR1 - Save GSTR1 data" on its developer portal, alongside a sample payload. The current final version is v5.0, published 23 February 2026. Earlier versions, v4.1 from February 2025 and v4.0 from July 2023, are still marked final, which is why two tools can both be right and produce different files.
The top level is the return period and a list of sections, each one a table of the return:
The sections carry the names a CA already knows from the portal, so a refusal can at least be placed. What a CA does not see on the portal is how little latitude the validator has.
- b2b, table 4: registered customers, keyed by their GSTIN
- b2cl, table 5: large inter-state supplies to unregistered customers
- b2cs, table 7: everything else to unregistered customers, grouped by place and rate
- cdnr, table 9B: credit and debit notes against registered customers
- hsn, table 12: the HSN summary
- doc_issue, table 13: the document series issued in the period
One unexpected key refuses the whole file
Nearly every object in the schema sets `additionalProperties: false`. In plain terms: if your file carries a field the schema does not name, the file is refused. Not the line, the file.
This is the single biggest difference between a JSON that a tool built and a JSON that a person assembled from an export. An export that helpfully carries an internal reference, a narration or a voucher number alongside the invoice number will be refused, and the message will not say which key was the problem.
It also means a tool has to be conservative about optional fields. The schema has `version` and `hash` at the top level as optional free text. What the offline tool itself writes in them is not stated in any official document we could find, so the honest thing is to leave them out rather than invent a value that might later be checked.
Important
GSTN's own published sample payload for v5.0 breaks the v5.0 schema: it still carries an "etin" field in the B2CL section that v5.0 removed. If you are building against the sample rather than the schema, you are building the previous version.
A date that does not exist
Every date in the file is DD-MM-YYYY, and the schema's pattern knows the calendar. It refuses 31-04, it refuses 30-02, and it refuses 29-02 in a year that is not a leap year.
That sounds like a problem nobody has, until you see where it comes from. A reshaping step that turns "2026-04-31" into "31-04-2026" does not know that 31 April is not a day. Something upstream produced an impossible date, the reshaping carried it faithfully, and the portal is the first thing in the chain that objects.
The fix is not a better date format. It is refusing the document at the point the impossible date appears and naming it, so the person sees which invoice is wrong instead of a rejected file.
This is the same shape of defect as an unreadable date in a Tally import, where the import appears to succeed and the voucher simply is not there. A date is the field most likely to arrive malformed and least likely to be looked at.
Pro tip
If a file is refused with nothing useful in the message, sort the invoices by date and look at the end of each month before you look at anything else.
Place of supply 99, and a GSTIN nobody checked
Two more that come from the books rather than the builder.
Place of supply 99. The state code list includes 99 for Centre Jurisdiction, and it is a perfectly real code in other contexts. Neither the domestic state field nor the foreign one in this schema accepts it. A validation written as "anything except 96" lets it through; a validation written as the schema's own pattern does not.
The customer's GSTIN. Accounting software hands over whatever was typed into the ledger master. If nothing checks it, a mistyped GSTIN goes straight into the `ctin` field and the file is refused on an invoice that is otherwise perfect. The schema allows four different GSTIN shapes, and a number that matches none of them never needed to reach the portal to be found wrong.
A related case worth deciding deliberately: a GSTIN whose check character is wrong still matches the pattern. Dropping that sale silently would be worse than filing it, so the right behaviour is to write it and report it plainly where the person filing will see it, not to quietly leave the invoice out of the return.
Rupees, paise and the ceiling nobody mentions
Every money field in the schema is `multipleOf: 0.01`, so figures go out in rupees to exactly two decimals. The safe way to get there is to hold amounts in paise as whole numbers through the whole calculation and divide once, at the moment of writing. Dividing early and adding up the results is how a return ends up a rupee away from the books.
The invoice value field also has a minimum of zero and a maximum, and a line's value and tax have a lower ceiling again. A misread amount, say a figure that picked up an extra digit from the column beside it, breaches the ceiling and takes the file down with it.
The same discipline applies on the purchase side. Where GST on bank charges belongs is a small figure, but it is the one most often rounded into the wrong head.
What to do with the part you cannot complete
No builder can classify every sale. Exports, SEZ supplies and anything with place of supply 96 are a different return shape, and a tool that quietly files them as ordinary B2B supplies is worse than a tool that refuses.
The useful behaviour is to produce the file for everything it is sure of, and hand back a plain list of what was left out and why, before anything is uploaded. A GSTR-1 a tool cannot complete is not a GSTR-1 it should pretend to complete.
That list is also the fastest review of the month's masters you will get: it is exactly the invoices where the GSTIN, the place of supply or the document number is not good enough to file.
Multistock invoices under GST are the other common source of lines a builder cannot place without being told.
Conclusion
The portal is not being difficult. It is validating against a published, versioned schema, and almost every refusal traces back to one of four things: a key the schema does not know, a date that is not a date, a code the field does not take, or a figure outside its range.
All four are findable before the upload, on the CA's own machine, from the same data the return is built from. Finding them there costs a minute. Finding them at the portal costs the afternoon.
Greenote builds the GSTR-1 file on your PC and validates it against that schema before you ever open the portal, then tells you plainly what it could not place. The filing stays yours. See what it covers.
Turn bank statements into Tally vouchers on your own PC
Greenote reads 100+ Indian banks and posts clean vouchers straight into Tally, from your own PC. The statement is not uploaded, and nothing is typed by hand.
Free trial: 2 days or 10 statements, no card. Works with Tally Prime & ERP 9.


