Bug 515052 - icc profile creation triggered assertion failure when saving .kra file or move krita across monitor (native Wayland)
Summary: icc profile creation triggered assertion failure when saving .kra file or mov...
Status: RESOLVED FIXED
Alias: None
Product: krita
Classification: Applications
Component: * Unknown (other bugs)
Version First Reported In: git master (please specify the git hash!)
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Krita Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2026-01-25 11:52 UTC by Ming Chuan
Modified: 2026-01-29 12:15 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ming Chuan 2026-01-25 11:52:05 UTC
SUMMARY

When krita is saving .kra file to a named destination, it hit assertion failure at https://invent.kde.org/graphics/krita/-/blob/master/plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp#L147 and failed to actually save the file

The issue seems to be pretty random and I cannot reproduce, nevertheless, it would be nice if krita can properly handle error and avoid crashing here when LCMS returns a nullptr

```
#0  0x00007ffff249df1c in __pthread_kill_implementation () from /nix/store/j193mfi0f921y0kfs8vjc1znnr45ispv-glibc-2.40-66/lib/libc.so.6
#1  0x00007ffff2441cee in raise () from /nix/store/j193mfi0f921y0kfs8vjc1znnr45ispv-glibc-2.40-66/lib/libc.so.6
#2  0x00007ffff2428941 in abort () from /nix/store/j193mfi0f921y0kfs8vjc1znnr45ispv-glibc-2.40-66/lib/libc.so.6
#3  0x00007ffff2cd74ee in qAbort() () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#4  0x00007ffff2d2e281 in qt_message(QtMsgType, QMessageLogContext const&, char const*, __va_list_tag*) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#5  0x00007ffff2cd8d42 in QMessageLogger::fatal(char const*, ...) const () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#6  0x00007ffff4b7f708 in kis_assert_common(char const*, char const*, int, bool, bool) () from /home/user/sources/krita/outputs/out/lib/libkritaglobal.so.21
#7  0x00007fffb154885b in IccColorProfile::IccColorProfile(QList<double> const&, ColorPrimaries, TransferCharacteristics) () from /home/user/sources/krita/outputs/out/lib/kritaplugins/kritalcmsengine.so
#8  0x00007fffb154ba8b in IccColorSpaceEngine::getProfile(QList<double> const&, ColorPrimaries, TransferCharacteristics) () from /home/user/sources/krita/outputs/out/lib/kritaplugins/kritalcmsengine.so
#9  0x00007ffff58da13d in KoColorSpaceRegistry::profileFor(QList<double> const&, ColorPrimaries, TransferCharacteristics) const () from /home/user/sources/krita/outputs/out/lib/libkritapigment.so.21
#10 0x00007ffff7c624ff in KisCanvasSurfaceColorSpaceManager::reinitializeSurfaceDescription(std::pair<KoColorConversionTransformation::Intent, QFlags<KoColorConversionTransformation::ConversionFlag> > const&) ()
   from /home/user/sources/krita/outputs/out/lib/libkritaui.so.21
#11 0x00007ffff7c632da in KisCanvasSurfaceColorSpaceManager::slotInterfacePreferredDescriptionChanged() () from /home/user/sources/krita/outputs/out/lib/libkritaui.so.21
#12 0x00007ffff2e2db09 in void doActivate<false>(QObject*, int, void**) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#13 0x00007ffff3f55f7e in KisSurfaceColorManagerInterface::sigPreferredSurfaceDescriptionChanged(KisSurfaceColorimetry::SurfaceDescription const&) ()
   from /home/user/sources/krita/outputs/out/lib/libkritasurfacecolormanagementapi.so.21
#14 0x00007ffff2e2db09 in void doActivate<false>(QObject*, int, void**) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#15 0x00007ffff2e2db09 in void doActivate<false>(QObject*, int, void**) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#16 0x00007ffff2e2db09 in void doActivate<false>(QObject*, int, void**) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#17 0x00007ffff0854052 in ffi_call_unix64 () from /nix/store/1z031fwbsc8jhmm7i39r6z6m1xn7rbza-libffi-3.5.2/lib/libffi.so.8
#18 0x00007ffff085275c in ffi_call_int () from /nix/store/1z031fwbsc8jhmm7i39r6z6m1xn7rbza-libffi-3.5.2/lib/libffi.so.8
#19 0x00007ffff08532ae in ffi_call () from /nix/store/1z031fwbsc8jhmm7i39r6z6m1xn7rbza-libffi-3.5.2/lib/libffi.so.8
#20 0x00007ffff15ad88c in wl_closure_invoke () from /nix/store/1b360ym6mfhwfj9s525bcympm5vav6np-wayland-1.24.0/lib/libwayland-client.so.0
#21 0x00007ffff15a9094 in dispatch_event () from /nix/store/1b360ym6mfhwfj9s525bcympm5vav6np-wayland-1.24.0/lib/libwayland-client.so.0
#22 0x00007ffff15aa2db in wl_display_dispatch_queue_pending () from /nix/store/1b360ym6mfhwfj9s525bcympm5vav6np-wayland-1.24.0/lib/libwayland-client.so.0
#23 0x00007ffff0968d92 in QtWaylandClient::EventThread::readAndDispatchEvents() () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6WaylandClient.so.6
#24 0x00007ffff0961691 in QtWaylandClient::QWaylandDisplay::flushRequests() () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6WaylandClient.so.6
#25 0x00007ffff2e1edd4 in QObject::event(QEvent*) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#26 0x00007ffff43a628f in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Widgets.so.6
#27 0x00007ffff7b56376 in KisApplication::notify(QObject*, QEvent*) () from /home/user/sources/krita/outputs/out/lib/libkritaui.so.21
#28 0x00007ffff2dbe6a8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#29 0x00007ffff2dc1f19 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#30 0x00007ffff30fc92f in postEventSourceDispatch(_GSource*, int (*)(void*), void*) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#31 0x00007ffff230182b in g_main_context_dispatch_unlocked () from /nix/store/f7rcazhd826xlcz43il4vafv28888cgj-glib-2.86.3/lib/libglib-2.0.so.0
#32 0x00007ffff2304e08 in g_main_context_iterate_unlocked.isra () from /nix/store/f7rcazhd826xlcz43il4vafv28888cgj-glib-2.86.3/lib/libglib-2.0.so.0
#33 0x00007ffff23056af in g_main_context_iteration () from /nix/store/f7rcazhd826xlcz43il4vafv28888cgj-glib-2.86.3/lib/libglib-2.0.so.0
#34 0x00007ffff30fc10d in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#35 0x00007ffff2dcc1eb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#36 0x00007ffff2dc7599 in QCoreApplication::exec() () from /nix/store/y12b5yjxvq0fwaskgjn2fl0q9v264w45-qtbase-6.10.1/lib/libQt6Core.so.6
#37 0x000055555555e11f in main ()
```

STEPS TO REPRODUCE
1. Open krita, create a new document
2. Try close the file, krita will ask if you want to save this file and where to save the file. Save the file.

OBSERVED RESULT


EXPECTED RESULT


SOFTWARE/OS VERSIONS
Linux/KDE Plasma: Hyprland (color management impl probably different than KDE)
Qt Version: 6.10.1
krita version: master branch at 2025-01-22

ADDITIONAL INFORMATION
Comment 1 Ming Chuan 2026-01-25 11:59:13 UTC
I don't think this really matters, but my LCMS is v2.17 without fastfloat. Krita appimage is still on 2.14
Comment 2 Ming Chuan 2026-01-27 14:21:13 UTC
I find another way to trigger this same assertion failure, it happens when I move krita from one monitor to the other then moving it back
Comment 3 Dmitry Kazakov 2026-01-27 15:02:08 UTC
Hi, Ming!

Do you compile Krita yourself? Could you check what values are passed to the constructor of IccColorProfile? Looking at the code, the only codepath I could imagine is that could cause such assert is that hyprland passing some really weird values as custom colorants...
Comment 4 Dmitry Kazakov 2026-01-27 16:20:30 UTC
Git commit 2d989aa34298c8d83a6f112ddd03f5b0eecae0b7 by Dmitry Kazakov.
Committed on 27/01/2026 at 15:09.
Pushed by dkazakov into branch 'master'.

Make asserts softer in IccColorProfile

If LCMS fails to create a profile, then just safe-assert and leave the profile
in an invalid state. It lets people save their files on some Wayland
compositors, like hyprland.

The bug itself is still valid, though it might be in the compositor, we don't
yet know.

M  +4    -4    plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp

https://invent.kde.org/graphics/krita/-/commit/2d989aa34298c8d83a6f112ddd03f5b0eecae0b7
Comment 5 Ming Chuan 2026-01-27 16:34:22 UTC
Yes I compiled from source, but I can also repro with latest appimage krita-6.0.0-prealpha-a457d92b67-x86_64.AppImage so I guess it's hyprland issue

```
(gdb) info args
this = 0x55556d56aca0
colorants = @0x7ffffffd0100: {<QListSpecialMethods<double>> = {<QListSpecialMethodsBase<double>> = {<No data fields>}, <No data fields>}, d = {d = 0x55555938f430, ptr = 0x55555938f440, size = 8}}
colorPrimariesType = PRIMARIES_UNSPECIFIED
transferFunction = TRC_ITU_R_BT_470_6_SYSTEM_M
(gdb) p colorants@8
$4 = {{<QListSpecialMethods<double>> = {<QListSpecialMethodsBase<double>> = {<No data fields>}, <No data fields>}, d = {d = 0x55555938f430, ptr = 0x55555938f440, size = 8}},
  {<QListSpecialMethods<double>> = {<QListSpecialMethodsBase<double>> = {<No data fields>}, <No data fields>}, d = {d = 0x400000002, ptr = 0x6e85c0c000000001, size = 140737488159632}},
  {<QListSpecialMethods<double>> = {<QListSpecialMethodsBase<double>> = {<No data fields>}, <No data fields>}, d = {d = 0x0, ptr = 0x0, size = 0}},
  {<QListSpecialMethods<double>> = {<QListSpecialMethodsBase<double>> = {<No data fields>}, <No data fields>}, d = {d = 0x0, ptr = 0x0, size = 0}},
  {<QListSpecialMethods<double>> = {<QListSpecialMethodsBase<double>> = {<No data fields>}, <No data fields>}, d = {d = 0x0, ptr = 0x0, size = 0}},
  {<QListSpecialMethods<double>> = {<QListSpecialMethodsBase<double>> = {<No data fields>}, <No data fields>}, d = {d = 0x0, ptr = 0x0, size = 0}},
  {<QListSpecialMethods<double>> = {<QListSpecialMethodsBase<double>> = {<No data fields>}, <No data fields>}, d = {d = 0x0, ptr = 0x0, size = 0}},
  {<QListSpecialMethods<double>> = {<QListSpecialMethodsBase<double>> = {<No data fields>}, <No data fields>}, d = {d = 0x0, ptr = 0x0, size = 0}}}
```
Comment 6 Ming Chuan 2026-01-27 16:37:34 UTC
Oops, I guess this is the right way to print it
```
(gdb) p (colorants.d.ptr)@8
$9 = {0x55555938f440, 0x8, 0x400000002, 0x6e85c0c000000001, 0x7ffffffd0390, 0x0, 0x0, 0x0}
```
Comment 7 Bug Janitor Service 2026-01-28 03:48:52 UTC
๐Ÿ›๐Ÿงน Thanks for your comment!

Automatically switching the status to REPORTED so the team can perform further triage.

In the future you may also do this yourself when providing needed information.
Comment 8 Dmitry Kazakov 2026-01-28 08:52:42 UTC
(In reply to Ming Chuan from comment #6)
> Oops, I guess this is the right way to print it
> ```
> (gdb) p (colorants.d.ptr)@8
> $9 = {0x55555938f440, 0x8, 0x400000002, 0x6e85c0c000000001, 0x7ffffffd0390,
> 0x0, 0x0, 0x0}
> ```

If you have Krita compiled, could you just add 

qDebug() << "colorants" << colorants;

in the beginning of the function and see what are the actual values passed to Krita before the crash?
Comment 9 Dmitry Kazakov 2026-01-28 09:15:14 UTC
Oh, you can also just try to download the latest nightly appimage, then, when the crash happens, press "Ignore" and check the output in the terminal. It should print all the info provided by hyprland into the terminal.
Comment 10 Ming Chuan 2026-01-28 13:07:56 UTC
```
SAFE ASSERT (krita): "iccProfile" in file /home/user/sources/krita/plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp, line 149
WARNING: failed to to create a profile for the compositor's preferred color space
     compositorPreferred = std::optional(SurfaceDescription(colorSpace: ColorSpace(primaries: Colorimetry(Red: xy(x: 0, y: 0), Green: xy(x: 0, y: 0), Blue: xy(x: 0, y: 0), White: xy(x: 0, y: 0)), transferFunction: NamedTransferFunction(transfer_function_gamma22), luminance: std::optional(Luminance(minLuminance: 2000, maxLuminance: 80, referenceLuminance: 80))), masteringInfo: MasteringInfo(primaries: Colorimetry(Red: xy(x: 0, y: 0), Green: xy(x: 0, y: 0), Blue: xy(x: 0, y: 0), White: xy(x: 0, y: 0)), luminance: MasteringLuminance(minLuminance: 0, maxLuminance: 0), maxCll: 0, maxFall: 0)))
     *requestedDescription = SurfaceDescription(colorSpace: ColorSpace(primaries: Colorimetry(Red: xy(x: 0, y: 0), Green: xy(x: 0, y: 0), Blue: xy(x: 0, y: 0), White: xy(x: 0, y: 0)), transferFunction: NamedTransferFunction(transfer_function_srgb), luminance: std::optional(Luminance(minLuminance: 2000, maxLuminance: 80, referenceLuminance: 80))))
```
Comment 11 Bug Janitor Service 2026-01-28 15:08:10 UTC
A possibly relevant merge request was started @ https://invent.kde.org/graphics/krita/-/merge_requests/2620
Comment 12 Dmitry Kazakov 2026-01-28 15:17:48 UTC
Hi, Ming!

Could you please test the patch?

https://invent.kde.org/graphics/krita/-/merge_requests/2620

The test plan is simple:

1) Activate "Preferred" surface management mode
2) Try to move the window between screens
3) Verify no crashes happen
4) Verify Help->Color Management Report doesn't have any "ERROR" lines telling about initialization failures.


PS:
And don't forget to report this bug to hyprland developers. That is definitely a bug in their implementation. The compositor should never send nonsense like that:

[3996291.759] {Default Queue} wp_image_description_info_v1#42.primaries(0, 0, 0, 0, 0, 0, 0, 0)
[3996291.761] {Default Queue} wp_image_description_info_v1#42.tf_power(10000)
[3996291.763] {Default Queue} wp_image_description_info_v1#42.tf_named(2)
[3996291.764] {Default Queue} wp_image_description_info_v1#42.luminances(2000, 80, 80)
[3996291.765] {Default Queue} wp_image_description_info_v1#42.target_primaries(0, 0, 0, 0, 0, 0, 0, 0)
[3996291.767] {Default Queue} wp_image_description_info_v1#42.target_luminance(0, 0)
[3996291.769] {Default Queue} wp_image_description_info_v1#42.target_max_cll(0)
[3996291.770] {Default Queue} wp_image_description_info_v1#42.target_max_fall(0)
[3996291.771] {Default Queue} wp_image_description_info_v1#42.done()

Primaries is an obligatory even according to the wayland protocol and it should report non-nonsense (well, the latter is not guaranteed by wayland though :) )
Comment 13 Dmitry Kazakov 2026-01-29 12:15:51 UTC
Git commit 601e40f7244bd69d646e09143bee571b8896073e by Dmitry Kazakov.
Committed on 29/01/2026 at 12:15.
Pushed by dkazakov into branch 'master'.

Fall back to unmanaged mode when Wayland reports nonsense

It seems like hyprland compositor is okay with sending us
nonsense instead of the preferred surface description:

wp_image_description_info_v1#42.primaries(0, 0, 0, 0, 0, 0, 0, 0)
wp_image_description_info_v1#42.tf_power(10000)
wp_image_description_info_v1#42.tf_named(2)
wp_image_description_info_v1#42.luminances(2000, 80, 80)
wp_image_description_info_v1#42.target_primaries(0, 0, 0, 0, 0, 0, 0, 0)
wp_image_description_info_v1#42.target_luminance(0, 0)
wp_image_description_info_v1#42.target_max_cll(0)
wp_image_description_info_v1#42.target_max_fall(0)
wp_image_description_info_v1#42.done()

Obviously, LCMS cannot create a profile with zero primaries,
so we should gracefully report the profile creation failure
and continue with different options (just downgrade color
management).

When everything has failed, we just add an "ERROR" message
to the color management report (though it is quite improbable
to happen).

M  +174  -137  libs/ui/KisCanvasSurfaceColorSpaceManager.cpp
M  +6    -0    libs/ui/KisCanvasSurfaceColorSpaceManager.h
M  +8    -1    plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp

https://invent.kde.org/graphics/krita/-/commit/601e40f7244bd69d646e09143bee571b8896073e