wekan/wekan · error · Meteor.Error
${error.name || error.message}
Error message
${error.name || error.message} What it means
After connecting successfully, the bind step (bindIfNecessary) runs inside runWithLdapDisconnect; if the bind rejects, the error is rethrown as new Meteor.Error(error.name || error.message). This surfaces directory-level bind errors — typically LDAPInvalidCredentials (error.name 49/invalidCredentials) or client-timeout names — to the admin as the Test Connection failure reason.
Source
Thrown at packages/wekan-ldap/server/testConnection.js:40
ldap = new LDAP();
await ldap.connect();
} catch (error) {
console.log(error);
// #6467/#6469: release anything opened before rethrowing, so a failed
// "Test Connection" does not leak a socket to the directory server.
if (ldap) {
await ldap.disconnect();
}
throw new Meteor.Error(error.message);
}
// #6467/#6469: always disconnect the test connection (success or failure),
// otherwise repeated admin "Test Connection" clicks leak connections too.
return await runWithLdapDisconnect(ldap, async () => {
try {
await ldap.bindIfNecessary();
} catch (error) {
throw new Meteor.Error(error.name || error.message);
}
return {
message: 'Connection_success',
params: [],
};
});
},
});
View on GitHub (pinned to eb1433158b)
Solutions
- Verify the bind credentials out-of-band: ldapsearch -H <url> -D <LDAP_BIND_DN> -w <LDAP_BIND_PASS> -b '' -s base.
- Use the full distinguished name for the bind user (e.g. cn=svc-wekan,ou=svc,dc=example,dc=com).
- Check the bind account is not expired/locked and its password matches the WeKan LDAP_BIND_PASS setting exactly.
- If no bind user is intended, confirm the directory permits anonymous search binds.
- Fix the setting and re-run Test Connection; the disconnect guard ensures no socket leaks between attempts.
Example fix
// before LDAP_BIND_DN = 'svc-wekan' // not a DN -> invalidCredentials LDAP_BIND_PASS = 'old-password' // after LDAP_BIND_DN = 'cn=svc-wekan,ou=services,dc=example,dc=com' LDAP_BIND_PASS = 'current-password'
Defensive patterns
Strategy: try-catch
Validate before calling
// verify bind credentials out-of-band before clicking Test Connection // ldapsearch -H ldaps://host:636 -D "$BIND_DN" -w "$BIND_PASS" -b '' -s base // non-zero exit means the credentials/DN are wrong regardless of WeKan settings
Type guard
const isBindError = (e) => /invalid credentials|invalidCredential|ldap.*49|LDAPInvalidCredentials/i.test(e?.name || e?.reason || '');
Try / catch
try {
const r = await Meteor.callAsync('ldap_test_connection');
} catch (e) {
// e.error carries error.name, e.reason the message from bindIfNecessary
if (isBindError(e)) {
showError('Bind rejected by the directory: check LDAP_BIND_DN and LDAP_BIND_PASS.');
}
} Prevention
- Store the bind user as a full DN, not a short account name or UPN
- Update WeKan's LDAP_BIND_PASS whenever the service-account password rotates
- Test bind credentials with ldapsearch before configuring WeKan
- Confirm the directory allows the intended bind (anonymous or authenticated)
- Verify the bind account is not expired or locked out by password policy
When it happens
Trigger: Meteor.call('ldap_test_connection') where the service bind fails: wrong LDAP_BIND_DN / LDAP_BIND_PASS, anonymous bind disallowed by the directory, expired/locked bind account, or the bind client timing out.
Common situations: Rotated service-account password not updated in WeKan; bind DN malformed (missing full DN, using UPN where DN required); password containing special characters mishandled; directory policy forbidding anonymous binds when no bind credentials configured.
Related errors
AI-assisted analysis of wekan/wekan@eb1433158b (2026-09-01).
Data as JSON: /api/errors/624b980fa10b8745.
Report an issue: GitHub.