Migrations

Importing accounts from other authentication plugins and moving data between storage backends.

mineLogin handles two different kinds of migration:

KindUse caseHow it runs
External migrationYou are switching from another authentication plugin (AuthMe, LimboAuth, …)Automatically on proxy startup
Internal migrationYou are keeping mineLogin but changing the storage backend (H2 → MySQL, …)Manually via console commands

Tip: Always create a full backup of both the source and the target database before starting any migration. Schedule migrations during low-traffic periods.


External Migration

mineLogin can import accounts directly from another authentication plugin. Passwords are not reset — the original hashes are imported as-is, so your players keep the passwords they already have.

Supported Plugins

Providers run in the order below. FastLogin runs last so that accounts imported from another plugin can still be upgraded to premium status.

OrderPluginProvider IDAuto-detected config
1AuthMe / AuthMeReloadedauthmeplugins/AuthMe/config.yml, plugins/AuthMeReloaded/config.yml
2DynamicBungeeAuthdynamicbungeeauthplugins/DynamicBungeeAuth/Config.yml
3JPremiumjpremiumplugins/JPremium/configuration.yml
4LibreLoginlibreloginplugins/LibreLogin/config.conf
5nLoginnloginplugins/nLogin/config.yml
6LimboAuthlimboauthplugins/limboauth/config.yml
7FastLoginfastloginplugins/FastLogin/config.yml

Supported Source Databases

DatabaseSupported
MySQL
MariaDB✅ (uses the MySQL driver)
SQLite
H2
PostgreSQL
MongoDB

Tip: The source database is only read, never modified. You can keep the old plugin installed until you have verified the migration.

How It Works

  1. Keep the source plugin data in its standard location, for example plugins/AuthMe or plugins/limboauth.
  2. Start the proxy. mineLogin reads the source plugin configuration and writes a migration file to plugins/mineLogin/migrations/<provider-id>.yml.
  3. Review the generated file. If mineLogin could read the source configuration, pls-change-me-after-configuring-this is already set to true and the migration runs on that same startup.
  4. After a successful run, completed is set to true so the migration never runs twice.

If mineLogin could not find the source plugin configuration, it writes an empty template instead and skips the migration. Fill in the connection details manually and set pls-change-me-after-configuring-this: true, then restart the proxy.

Accounts that already exist in mineLogin are updated rather than duplicated, so re-running a migration against a partially imported database is safe.

Tip: A failed migration stops the proxy on purpose. This prevents players from registering new accounts on top of a half-imported database.

Migration File Reference

provider-id: limboauth
pls-change-me-after-configuring-this: true
completed: false
driver: H2
host: 127.0.0.1
port: 3306
database: limboauth
user: your-remote-username
password: user-db-password
use-ssl: false
file-db-path: plugins/limboauth/limboauth-v2.mv.db
table-name: AUTH
columns:
  username: NICKNAME
  password: HASH
OptionTypeDescription
provider-idStringIdentifies the source plugin. Never change this value.
pls-change-me-after-configuring-thisBooleanMigration only runs when this is true
completedBooleanManaged by the plugin — set to true after a successful run
driverEnumSource database type: MYSQL, SQLITE or H2
hostStringSource database address (MySQL only)
portIntegerSource database port (MySQL only)
databaseStringSource database name (MySQL only)
userStringSource database user (MySQL only)
passwordStringSource database password (MySQL only)
use-sslBooleanEnable SSL for the source connection (MySQL only)
file-db-pathStringPath to the source file, relative to the server root (SQLite/H2 only)
table-nameStringSource table name
columnsMapColumn name overrides — keys depend on the provider

Tip: You only need to touch columns if the source plugin uses a non-standard schema. Leave it as generated otherwise.


AuthMe

Reads the AuthMe account table directly. The plugin folder may be named either AuthMe or AuthMeReloaded.

Source databases: MySQL, MariaDB, SQLite  |  Default table: authme

AuthMe columnmineLogin fieldcolumns key
realnameUsernameusername
usernameUsername fallbackfallback-username
passwordPassword hashpassword
saltSaltsalt
emailEmailemail
regipRegister addressregister-address
ipLast join addresslast-join-address
regdateRegister timeregister-time
lastloginLast join timelast-join-time

Column names are read from the DataSource section of the AuthMe config, so custom schemas are picked up automatically.

Passwords: the hash format is detected automatically. If the salt column is missing, the salt is extracted from $SHA$salt$hash values.

Premium accounts: AuthMe does not track premium status, so every account is imported as cracked with an offline UUID generated from the username. Run the FastLogin migration afterwards to restore premium status.

Tip: Unlike the other providers, AuthMe aborts the migration on an unrecognised hash format instead of skipping the account. This is intentional — a silently skipped AuthMe account would look identical to a never-registered one.


DynamicBungeeAuth

Source databases: MySQL only  |  Default table: playerdata

DynamicBungeeAuth columnmineLogin fieldcolumns key
nameUsernameusername
uuidAccount UUIDuuid
passwordPassword hashpassword
saltSaltsalt
premiumPremium statepremium
emailEmailemail
reg_ipRegister addressregister-address
log_ipLast join addresslast-join-address
firstjoinRegister timeregister-time
lastjoinLast join timelast-join-time

Passwords: the hash algorithm is read from Options.PasswordHash and stored under the hash-algorithm key in the migration file.

AlgorithmRequires salt column
AUTHME-SHA256No
SHA256Yes
SHA512 (default)Yes
SMD5Yes

Premium accounts: taken from the boolean premium column.


JPremium

Source databases: MySQL only  |  Default table: user_profiles

JPremium columnmineLogin fieldcolumns key
lastNicknameUsernameusername
uniqueIdAccount UUIDunique-id
premiumIdPremium UUIDpremium-id
hashedPasswordPassword hashpassword
lastAddressLast join addresslast-join-address
firstSeenRegister timeregister-time
lastSeenLast join timelast-join-time

Passwords: SHA256$, SHA512$, BCRYPT$ and plain $2a$ hashes are supported.

Premium accounts: an account with a filled premiumId is imported as premium and keeps that UUID.

SSL is enabled unless the JPremium storageProperties list contains useSSL=false.


LibreLogin

Reads the HOCON configuration at plugins/LibreLogin/config.conf to detect whether LibreLogin runs on SQLite or MySQL.

Source databases: MySQL, SQLite  |  Default table: librepremium_data

LibreLogin columnmineLogin fieldcolumns key
last_nicknameUsernameusername
uuidAccount UUIDuuid
premium_uuidPremium UUIDpremium-id
hashed_passwordPassword hashpassword
saltSaltsalt
algoHash algorithmalgorithm
emailEmailemail
secret2FA secretsecret
ipLast join addresslast-join-address
joinedRegister timeregister-time
last_authenticationLast join timelast-join-time
last_seenLast join time fallbacklast-seen-time

Passwords: the per-account algo column decides how the hash is rebuilt. Supported values are SHA-256, SHA-512, BCRYPT-2A, BCRYPT-2B, BCRYPT-2X, BCRYPT-2Y and ARGON-2ID. LibreLogin splits BCrypt and Argon2 hashes across the salt and algo columns, so mineLogin reassembles them into standard hash strings.

Premium accounts: an account with a filled premium_uuid is imported as premium and keeps that UUID.

Two-factor authentication: TOTP secrets are imported from the secret column.


nLogin

Source databases: MySQL, SQLite  |  Default table: nlogin

nLogin columnmineLogin fieldcolumns key
last_nameUsernameusername
unique_idAccount UUIDunique-id
mojang_idPremium UUIDpremium-id
passwordPassword hashpassword
last_ipLast join addresslast-join-address
creation_dateRegister timeregister-time
last_seenLast join timelast-join-time

Passwords: BCrypt ($2a$), Argon2 ($argon2), AuthMe-style ($SHA$), $SHA256$ and $SHA512$ hashes are supported.

Premium accounts: an account with a filled mojang_id is imported as premium and keeps that UUID.

Accounts without a unique_id are skipped.


LimboAuth

LimboAuth stores every account in a single AUTH table. mineLogin reads it directly, so no export step is needed.

Source databases: H2, MySQL, MariaDB, SQLite  |  Default table: AUTH

LimboAuth columnmineLogin fieldcolumns key
NICKNAMEUsernameusername
LOWERCASENICKNAMEUsername fallbackfallback-username
HASHPassword hashpassword
UUIDAccount UUIDuuid
PREMIUMUUIDPremium UUIDpremium-id
TOTPTOKEN2FA secretsecret
IPRegister addressregister-address
LOGINIPLast join addresslast-join-address
REGDATERegister timeregister-time
LOGINDATELast join timelast-join-time

Passwords: LimboAuth hashes with BCrypt, which mineLogin supports natively — players log in with their existing passwords immediately. LimboAuth can also keep hashes imported from other plugins through its own MIGRATION_HASH option; those formats are detected automatically, and accounts using an unsupported format are skipped with a console warning.

Premium accounts: an account with an empty HASH and a filled PREMIUMUUID logs in through Mojang instead of using a password. These are imported as premium accounts keeping their premium UUID and no password. An account with neither a password nor a premium UUID is skipped.

Two-factor authentication: TOTP secrets from TOTPTOKEN are imported, so players keep their 2FA without scanning a new QR code. LimboAuth has no recovery codes, so mineLogin recovery codes start out empty.

Storage backends:

LimboAuth storage-typeSupportedDefault source path
h2plugins/limboauth/limboauth-v2.mv.db
mysql
mariadb
sqliteplugins/limboauth/limboauth.db
postgresql

Tip: If only the legacy H2 v1 file (limboauth.mv.db) exists, start LimboAuth once so it upgrades the file to v2 before migrating. mineLogin logs a warning in this case.


FastLogin

FastLogin only tracks which players are premium — it stores no passwords. This provider therefore never creates accounts, it only upgrades accounts that already exist in mineLogin. That is why it runs last, after the password-carrying providers.

Source databases: MySQL, MariaDB, SQLite  |  Default table: premium

FastLogin columnmineLogin fieldcolumns key
NameUsernameusername
UUIDPremium UUIDuuid
PremiumPremium statepremium

Rows with Premium = false are ignored. Rows for players who do not exist in mineLogin are reported as skipped — import their passwords from another plugin first.


Internal Migration

Use this to move existing mineLogin data between storage backends, for example from H2 to MySQL. All commands must be executed from the proxy console.

Step 1: Export Data

Run the export command in the proxy console:

minelogin internalMigration export

Monitor the console for confirmation that all user data has been exported.

Step 2: Update Configuration

Stop the proxy server and change the data-type and connection details in your configuration to the new database backend. Save the file.

Step 3: Restart and Import

Start the proxy server, then run:

minelogin internalMigration import

Wait for the console to confirm that the import has completed. Prevent new players from joining until the migration is finished.

Step 4: Verify

Check that player data is intact by using /ml userinfo <username> on a few accounts. Once verified, you can remove the old database and temporary files.


Troubleshooting

ProblemCauseSolution
Migration is skipped on startuppls-change-me-after-configuring-this is falseFill in the migration file and set it to true
Migration is skipped after a successful runcompleted is trueSet it back to false to run it again
Proxy stops with a validation errorSource table or column does not existCheck table-name and columns against the source database
Source database file does not existWrong file-db-pathThe path is relative to the server root, not to the plugin folder
Accounts reported as skippedMissing password, missing premium UUID, or unsupported hash formatReview the console warnings — these accounts need to register again
Everything skipped in a FastLogin runThe accounts do not exist in mineLogin yetImport passwords from the original auth plugin first
Unsupported source database typeThe source plugin uses PostgreSQL or MongoDBExport the data to MySQL, SQLite or H2 first