This is because UTF-8 in SQLite is actually "a stream of bytes". If you put "garbage" into a UTF-8 field (such as the common "Modified UTF-8" which encodes NUL as C0 80) SQLite will dutifully store it and return it back to you as long as you ask for it in UTF-8. Or for that matter, you can store any encoding that does not embed a null in a UTF-8 text field, you are just responsible for knowing what to do with it in the end. Such is the nature of SQLite text fields. One could write a user defined function, say "valid_utf8", that verifies a field is truly UTF-8 and use it in check constraints if they really want to guarantee that no ill formed UTF-8 is injected. At this point SQLite couldn't (so it seems to me) change how it stores UTF-8 text fields without breaking someone.