OpenFire 5.0.1 Base64 Error when uploading avatars

Freshly installed OpenFire 5.0.1.
My client throws errors when trying to publish vCard with an avatar.

Here is the log:

2025.08.06 08:02:19.439 ERROR [socket_c2s-worker-15]: org.jivesoftware.openfire.handler.IQHandler - Internal Server Error
java.lang.IllegalArgumentException: Illegal base64 character 20
    at java.util.Base64$Decoder.decode0(Base64.java:852) ~[?:?]
    at java.util.Base64$Decoder.decode(Base64.java:570) ~[?:?]
    at java.util.Base64$Decoder.decode(Base64.java:593) ~[?:?]
    at org.jivesoftware.openfire.vcard.PhotoResizer.resizeAvatar(PhotoResizer.java:101) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.vcard.DefaultVCardProvider.loadVCard(DefaultVCardProvider.java:93) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.vcard.VCardManager.getOrLoadVCard(VCardManager.java:245) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.vcard.VCardManager.getVCard(VCardManager.java:238) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.handler.IQvCardHandler.handleIQ(IQvCardHandler.java:139) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.handler.IQHandler.process(IQHandler.java:125) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.IQRouter.handle(IQRouter.java:403) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.IQRouter.route(IQRouter.java:106) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.spi.PacketRouterImpl.route(PacketRouterImpl.java:74) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.net.StanzaHandler.processIQ(StanzaHandler.java:392) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.net.ClientStanzaHandler.processIQ(ClientStanzaHandler.java:90) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:334) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.net.StanzaHandler.processStanza(StanzaHandler.java:222) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:114) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.nio.NettyConnectionHandler.channelRead0(NettyConnectionHandler.java:142) ~[xmppserver-5.0.1.jar:5.0.1]
    at org.jivesoftware.openfire.nio.NettyConnectionHandler.channelRead0(NettyConnectionHandler.java:50) ~[xmppserver-5.0.1.jar:5.0.1]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:289) ~[netty-handler-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.traffic.AbstractTrafficShapingHandler.channelRead(AbstractTrafficShapingHandler.java:506) ~[netty-handler-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1515) ~[netty-handler-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1378) ~[netty-handler-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1427) ~[netty-handler-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530) ~[netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469) ~[netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) ~[netty-codec-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1357) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:868) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:796) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:732) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:658) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.118.Final.jar:4.1.118.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.118.Final.jar:4.1.118.Final]

Have you tried without the resizer plugin? looks like its a plugin issue rather than Openfire.

I do not have Avatar Resizer plugin installed on the server. It is a fresh install without any modifications.

Does the picture file name contain any foreigner characters? And Which Client are you using?

The picture name and what’s on it does not matter, right now it’s just “avatar.jpg”. I am using Psi 1.3.
Tried using Spark, but it tells me that my server does not support vCards and it throws the same error in the console.

I tried with Spark and everything worked normally here. anything else you can think of on how to replicate the issue?

The char with code 20 is a space symbol. I remember there was some changes about the base64 decoder. See a similar problem

Apparently, your database has an avatar stored for you in a format that’s not recognized. I wonder how that came to be.

Can you please provide us with the exact database content for this query (replacing the question mark with the username of the affected user):

SELECT vcard FROM ofVCard WHERE username=?

As a work-around for the problem, you can set a property named avatar.resize.enable-on-load to the value false

This is what’s in the database:

<vCard xmlns="vcard-temp"><FN>Maccer</FN><PHOTO><TYPE>image/jpeg</TYPE><BINVAL>/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCg
kICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQ
EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCABAAE
ADAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIE
AwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJi
coKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWW
l5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09f
b3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQA
AQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKj
U2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJma
oqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9
oADAMBAAIRAxEAPwD4Brj5mcQtHMwEzRzMBfwquZAJmjmQBmnzIBaG0gClzICX7OP79QAfZx/f
oA+jf2cv2SPFfxWtV8RS+DdU1a0dwIIU/cW5Xg7pZiQoz2QHOOSOQK+UzfN8VzvD4Bbby8+y9O
rOilSc/esdmnwj+Emt+Lb34c6PYeEL7WbOSGGWCxv1ISSd9kMS3XyxSSM2FUK5y3HU4rzPYcRU
YLESqO2+rX5WNfYxvZI4af8AZ38FWfirU/D99PrltPpLK11avInyAlgYi23IZSvuSMc1dfiHM8
PSjKpCKcrrVO911ttZmPs0pOEtGi/qXwJ+GENi97exTaXb2yl5Zv7QYBVGAS7OSOCy5wOpHrXN
hM+zjEu1Fc7/AMOn6fmV7KLOG+NH7Ouu/DDRLHxhBZaqNDv5vs6SXluQA5BI2yAbW6EEcMCOR6
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
pp9SqkUqTij//Z</BINVAL></PHOTO></vCard>

Thanks, that was very helpful.

Openfire is overly strict. It allows newlines, but only when they’re used to wrap every 76 characters. The data that you’ve provided is using 74.

Openfire should be less strict (various XMPP specifications even declare that any whitespace characters in Base64 encoded data MUST be ignored).

I’ve created a new ticket for this issue: OF-3112. I expect this to be fixed in release 5.0.2 of Openfire.