theonedev/onedev · critical · RuntimeException

Illegal data version format in database

Error message

Illegal data version format in database

What it means

readDbDataVersion expects exactly one row in the ModelVersion table. After reading the first row's version value, if resultset.next() returns true again, multiple version rows exist, which is an illegal format, so it throws 'Illegal data version format in database'.

Source

Thrown at server-core/src/main/java/io/onedev/server/data/DefaultDataService.java:309

		JdbcEnvironment environment = getMetadata().getDatabase()
				.getServiceRegistry().getService(JdbcEnvironment.class);
		Identifier identifier = Identifier.toIdentifier(fieldName);
		return physicalNamingStrategy.toPhysicalColumnName(identifier, environment).getText();
	}
	
	private String readDbDataVersion(Connection conn) {
		try {
			var versionTableName = getTableName(ModelVersion.class);
			if (tableExists(conn, versionTableName)) {
				try (	Statement stmt = conn.createStatement();
						 ResultSet resultset = stmt.executeQuery("select " + getColumnName(ModelVersion.PROP_VERSION_COLUMN) + " from " + versionTableName)) {
					if (!resultset.next()) {
						throw new RuntimeException("No data version found in database: this is normally caused "
								+ "by unsuccessful restore/upgrade, please clean the database and try again");
					}
					String dataVersion = resultset.getString(1);
					if (resultset.next())
						throw new RuntimeException("Illegal data version format in database");
					return dataVersion;
				}
			} else {
				return null;
			}
		} catch (Exception e) {
			if (e.getMessage() != null && e.getMessage().contains("ORA-00942")) 
				return null;
			else
				throw ExceptionUtils.unchecked(e);
		}
	}

	private File getVersionFile(File dataDir) {
		File versionFile = new File(dataDir, ModelVersion.class.getSimpleName() + "s.xml");
		if (!versionFile.exists())
			versionFile = new File(dataDir, "VersionTables.xml");
		return versionFile;

View on GitHub (pinned to d44925c47c)

Solutions

  1. Delete the duplicate rows so exactly one version row remains: delete from <ModelVersion table> where id != (select min(id) ...)
  2. Verify the remaining version value matches the OneDev version that wrote the DB
  3. If unsure, drop/recreate the DB and restore from a clean backup
  4. Re-run the restore with the restore-db script from the correct backup

Example fix

-- keep only one version row
delete from model_version where id not in (select min(id) from model_version);
Defensive patterns

Strategy: validation

Validate before calling

int rows = countRows(conn, "model_version");
if (rows != 1) dedupeOrRestoreModelVersionTable();

Try / catch

try { migrate(); } catch (RuntimeException e) { if (e.getMessage().contains("Illegal data version format")) { deleteDuplicateVersionRows(conn); } }

Prevention

When it happens

Trigger: The ModelVersion table contains more than one row, e.g. from duplicate inserts during a botched restore, manual data import, or a migration bug.

Common situations: Restoring backup data twice without cleaning the DB, merging databases, or manual SQL manipulation of the version table.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/34dd27a2333757cc. Report an issue: GitHub.