You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] Rollback of controller fails when older binary lacks DOWN files for newer schema versions #1881
I have searched the existing issues to avoid creating a duplicate
By submitting this issue, you agree to follow our Code of Conduct
I am using the latest version of the software
I have tried to clear cache/cookies or used incognito mode (if ui-related)
I can consistently reproduce this issue
🎯 Affected Service(s)
Controller Service
🚦 Impact/Severity
Blocker
🐛 Bug Description
When the kagent controller is downgraded to a previous version, the older controller fails to start if the newer version applied schema migrations that are unknown to the older version. This was observed when attempting to rollback after a failed upgrade from 0.9.0 to 0.9.3´. The .down.sql files for those migrations are embedded only in the newer container. The older container can neither roll the schema back nor start against the newer schema, resulting in a crash loop.
@onematchfox Thanks for raising this issue. Can you provide more context on the failed upgrade aspect? On each crash loop, the Kagent controller applies all down migrations before crashing, but without scaling to 0 before downgrading, the migrations would just run again.
I think we will need to have a good solution in these cases, but in the meantime, you should be able to manually apply the down migrations with golang-migrate directly:
Can you provide more context on the failed upgrade aspect?
Sorry, this is misleading. The upgrade didn't fail as such... I upgraded to v0.9.3 successfully to test the new version but then decided to rollback to v0.9.0 and was unable to do so.
Thanks for the tip on the workaround. Will bear that in mind if this comes up again before we find an automated way of achieving this. On that, do you have any thoughts on how we might do this? It doesn't seem like golang-migrate has a good solution to this. The only thing I could really come up with was to store the down scripts in a database table when applying the migrations so that they could be retrieved and used by any version.
Sorry, this is misleading. The upgrade didn't fail as such... I upgraded to v0.9.3 successfully to test the new version but then decided to rollback to v0.9.0 and was unable to do so.
Ah, ok. I was worried that we had broken something on the upgrade.
On that, do you have any thoughts on how we might do this? It doesn't seem like golang-migrate has a good solution to this. The only thing I could really come up with was to store the down scripts in a database table when applying the migrations so that they could be retrieved and used by any version.
That is one approach I've been considering. I was also thinking that the kagent cli could have the migrations embedded so that you can run kagent migrate down or something similar. That would of course require the newer version of the cli to be used, but could be an option.
I was also thinking that the kagent cli could have the migrations embedded so that you can run kagent migrate down or something similar. That would of course require the newer version of the cli to be used, but could be an option.
Yeah, this doesn't really work well in a GitOps environment or if someone in the cluster decided to kubectl rollout undo 😞
Another alternative would be to adopt the expand/contract pattern and thereby lift the constraint that old versions cannot run against newer schemas. But, this does require engineering discipline as breaking schema changes need to be staged across multiple versions as well as some form of support guarantee by the maintainers along the lines of "rollback is supported across N minor versions" for example.
I think this approach would work as an incremental improvement step. We have some ideas for how to make the migration/rollback process more robust, but that'll be a rewrite of much of the migrator logic.
Activity
iplay88keys commentedon May 18, 2026
@onematchfox Thanks for raising this issue. Can you provide more context on the failed upgrade aspect? On each crash loop, the Kagent controller applies all down migrations before crashing, but without scaling to 0 before downgrading, the migrations would just run again.
I think we will need to have a good solution in these cases, but in the meantime, you should be able to manually apply the down migrations with
golang-migratedirectly:golang-migrateonematchfox commentedon May 19, 2026
Sorry, this is misleading. The upgrade didn't fail as such... I upgraded to
v0.9.3successfully to test the new version but then decided to rollback tov0.9.0and was unable to do so.Thanks for the tip on the workaround. Will bear that in mind if this comes up again before we find an automated way of achieving this. On that, do you have any thoughts on how we might do this? It doesn't seem like
golang-migratehas a good solution to this. The only thing I could really come up with was to store the down scripts in a database table when applying the migrations so that they could be retrieved and used by any version.iplay88keys commentedon May 19, 2026
Ah, ok. I was worried that we had broken something on the upgrade.
That is one approach I've been considering. I was also thinking that the
kagentcli could have the migrations embedded so that you can runkagent migrate downor something similar. That would of course require the newer version of the cli to be used, but could be an option.onematchfox commentedon Jun 3, 2026
Yeah, this doesn't really work well in a GitOps environment or if someone in the cluster decided to
kubectl rollout undo😞Another alternative would be to adopt the expand/contract pattern and thereby lift the constraint that old versions cannot run against newer schemas. But, this does require engineering discipline as breaking schema changes need to be staged across multiple versions as well as some form of support guarantee by the maintainers along the lines of "rollback is supported across N minor versions" for example.
onematchfox commentedon Jun 4, 2026
I see this is already documented as having been adopted in https://github.com/kagent-dev/kagent/blob/main/.claude/skills/kagent-dev/references/database-migrations.md#backward-compatible-schema-changes so maybe we can just not return an error if we're running an older binary against a newer schema? Will put a PR together for this in the meantime.
iplay88keys commentedon Jun 5, 2026
I think this approach would work as an incremental improvement step. We have some ideas for how to make the migration/rollback process more robust, but that'll be a rewrite of much of the migrator logic.
fix(controller): skip DB migration when DB schema is ahead of binary (#…