Spring Boot
Kotlin
@Value Annotation
Troubleshooting
Configuration

Spring Boot with Kotlin - Value annotation not working as expected

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

When @Value appears broken in a Kotlin Spring Boot project, the root cause is usually not Kotlin itself. It is usually one of a few practical issues: the class is not Spring-managed, the property key is wrong, the ${...} expression was written incorrectly for Kotlin strings, or @Value is being used where @ConfigurationProperties would be a better fit.

Kotlin does make some of these mistakes more visible. Constructor injection, non-null types, and immutable properties expose configuration problems sooner than older Java-style field injection patterns.

Make Sure the Bean Is Actually Managed by Spring

@Value works only when Spring creates the object:

kotlin
1import org.springframework.beans.factory.annotation.Value
2import org.springframework.stereotype.Component
3
4@Component
5class ApiSettings(
6    @Value("\${app.api.base-url}")
7    val baseUrl: String
8)

If you instantiate the class manually with ApiSettings(...), no injection happens. That is the first thing to verify before changing annotations or properties files.

Kotlin Strings Need Escaped ${...} in Annotations

This is one of the most Kotlin-specific mistakes. Because Kotlin uses $ for string interpolation, the @Value expression must escape the dollar sign:

kotlin
@Value("\${app.mode}")

Not this:

kotlin
@Value("${app.mode}")

The second form is interpreted by Kotlin as string interpolation, not as the Spring placeholder you intended.

Prefer Constructor Injection in Kotlin

Constructor injection works naturally with immutable Kotlin code:

kotlin
1import org.springframework.beans.factory.annotation.Value
2import org.springframework.stereotype.Component
3
4@Component
5class ModeConfig(
6    @Value("\${app.mode:dev}")
7    val mode: String
8)

This is usually safer than field injection with lateinit, because the dependency is provided at construction time and the property can remain a val.

Field injection can work:

kotlin
1@Component
2class LegacyConfig {
3    @Value("\${app.mode}")
4    lateinit var mode: String
5}

But it is easier to misuse, especially in tests and manual object creation.

Verify Property Keys and Profiles

A lot of @Value failures are simple configuration mismatches:

properties
app.api.base-url=https://api.example.com
app.mode=prod

Then check the active profile explicitly:

bash
java -jar app.jar --spring.profiles.active=dev

If the wrong profile is active, the property may genuinely not exist in the resolved environment. Before assuming the annotation is broken, confirm:

  • the property key spelling
  • the active profile
  • the property source that should provide the value

Use @ConfigurationProperties for Grouped Settings

If you have many related settings, multiple @Value annotations are usually the wrong abstraction. A typed properties class is clearer:

kotlin
1import org.springframework.boot.context.properties.ConfigurationProperties
2
3@ConfigurationProperties(prefix = "app.auth")
4data class AuthProperties(
5    var issuer: String = "",
6    var audience: String = "",
7    var tokenTtlSeconds: Long = 3600
8)

Then enable it in configuration:

kotlin
1import org.springframework.boot.context.properties.EnableConfigurationProperties
2import org.springframework.context.annotation.Configuration
3
4@Configuration
5@EnableConfigurationProperties(AuthProperties::class)
6class AuthConfig

This is usually easier to validate, test, and maintain than a scattering of unrelated @Value expressions.

Common Pitfalls

The biggest Kotlin-specific mistake is forgetting to escape the dollar sign in the placeholder string. If the annotation uses "${...}" instead of "\${...}", the expression is wrong before Spring even sees it.

Another common issue is putting @Value on a class that Spring does not manage. Manual instantiation bypasses the entire injection process.

Developers also use @Value on too many individual fields when the configuration really belongs in a typed properties object. That makes the code harder to read and harder to validate.

Finally, do not ignore the simple possibility of a bad property key or wrong profile. Those remain the most common failures in ordinary Spring Boot projects.

Summary

  • '@Value works only on Spring-managed objects.'
  • In Kotlin, write placeholders as "\${...}", not "${...}".
  • Constructor injection is the cleanest default for Kotlin Spring code.
  • Check property keys and active profiles before deeper debugging.
  • Use @ConfigurationProperties when several related settings belong together.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.