diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 2ee5d9e6d63665d4dd5c04c34a0da3a12d720cea..b75c029a516adf9ff6daf0001f80569944357352 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -17,6 +17,32 @@ file(GLOB LIB_SOURCES ${LAMMPS_SOURCE_DIR}/*.cpp)
 file(GLOB LMP_SOURCES ${LAMMPS_SOURCE_DIR}/main.cpp)
 list(REMOVE_ITEM LIB_SOURCES ${LMP_SOURCES})
 
+# Utility functions
+function(list_to_bulletpoints result)
+    list(REMOVE_AT ARGV 0)
+    set(temp "")
+    foreach(item ${ARGV})
+        set(temp "${temp}* ${item}\n")
+    endforeach()
+    set(${result} "${temp}" PARENT_SCOPE)
+endfunction(list_to_bulletpoints)
+
+function(validate_option name values)
+    string(TOLOWER ${${name}} needle_lower)
+    string(TOUPPER ${${name}} needle_upper)
+    list(FIND ${values} ${needle_lower} IDX_LOWER)
+    list(FIND ${values} ${needle_upper} IDX_UPPER)
+    if(${IDX_LOWER} LESS 0 AND ${IDX_UPPER} LESS 0)
+        list_to_bulletpoints(POSSIBLE_VALUE_LIST ${${values}})
+        message(FATAL_ERROR "\n########################################################################\n"
+                            "Invalid value '${${name}}' for option '${name}'\n"
+                            "\n"
+                            "Possible values are:\n"
+                            "${POSSIBLE_VALUE_LIST}"
+                            "########################################################################")
+    endif()
+endfunction(validate_option)
+
 # Cmake modules/macros are in a subdirectory to keep this file cleaner
 set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Modules)
 
@@ -131,11 +157,14 @@ else()
   list(APPEND LAMMPS_LINK_LIBS mpi_stubs)
 endif()
 
+
 set(LAMMPS_SIZES "smallbig" CACHE STRING "LAMMPS size limit")
-set_property(CACHE LAMMPS_SIZES PROPERTY STRINGS smallbig bigbig smallsmall)
-string(TOUPPER ${LAMMPS_SIZES} LAMMPS_SIZES_DEFINE)
-add_definitions(-DLAMMPS_${LAMMPS_SIZES_DEFINE})
-set(LAMMPS_API_DEFINES "${LAMMPS_API_DEFINES} -DLAMMPS_${LAMMPS_SIZES_DEFINE}")
+set(LAMMPS_SIZES_VALUES smallbig bigbig smallsmall)
+set_property(CACHE LAMMPS_SIZES PROPERTY STRINGS ${LAMMPS_SIZES_VALUES})
+validate_option(LAMMPS_SIZES LAMMPS_SIZES_VALUES)
+string(TOUPPER ${LAMMPS_SIZES} LAMMPS_SIZES)
+add_definitions(-DLAMMPS_${LAMMPS_SIZES})
+set(LAMMPS_API_DEFINES "${LAMMPS_API_DEFINES} -DLAMMPS_${LAMMPS_SIZES}")
 
 # posix_memalign is not available on Windows
 if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
@@ -219,7 +248,9 @@ if(PKG_KSPACE)
   else()
     set(FFT "KISS" CACHE STRING "FFT library for KSPACE package")
   endif()
-  set_property(CACHE FFT PROPERTY STRINGS KISS ${FFTW} MKL)
+  set(FFT_VALUES KISS ${FFTW} MKL)
+  set_property(CACHE FFT PROPERTY STRINGS ${FFT_VALUES})
+  validate_option(FFT FFT_VALUES)
   if(NOT FFT STREQUAL "KISS")
     find_package(${FFT} REQUIRED)
     if(NOT FFT STREQUAL "FFTW3F")
@@ -233,10 +264,12 @@ if(PKG_KSPACE)
     add_definitions(-DFFT_KISS)
   endif()
   set(FFT_PACK "array" CACHE STRING "Optimization for FFT")
-  set_property(CACHE FFT_PACK PROPERTY STRINGS array pointer memcpy)
+  set(FFT_PACK_VALUES array pointer memcpy)
+  set_property(CACHE FFT_PACK PROPERTY STRINGS ${FFT_PACK_VALUES})
+  validate_option(FFT_PACK FFT_PACK_VALUES)
   if(NOT FFT_PACK STREQUAL "array")
-    string(TOUPPER ${FFT_PACK} FFT_PACK_DEFINE)
-    add_definitions(-DFFT_PACK_${FFT_PACK_DEFINE})
+    string(TOUPPER ${FFT_PACK} FFT_PACK)
+    add_definitions(-DFFT_PACK_${FFT_PACK})
   endif()
 endif()
 
@@ -747,9 +780,9 @@ if(PKG_USER-INTEL)
     endif()
 
     set(INTEL_ARCH "cpu" CACHE STRING "Architectures used by USER-INTEL (cpu or knl)")
-    set_property(CACHE INTEL_ARCH PROPERTY STRINGS cpu knl)
-
-
+    set(INTEL_ARCH_VALUES cpu knl)
+    set_property(CACHE INTEL_ARCH PROPERTY STRINGS ${INTEL_ARCH_VALUES})
+    validate_option(INTEL_ARCH INTEL_ARCH_VALUES)
 
     if(INTEL_ARCH STREQUAL "knl")
       set(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} -xHost -qopenmp -qoffload")
@@ -808,25 +841,29 @@ if(PKG_GPU)
                     ${GPU_SOURCES_DIR}/fix_gpu.cpp)
 
     set(GPU_API "opencl" CACHE STRING "API used by GPU package")
-    set_property(CACHE GPU_API PROPERTY STRINGS opencl cuda)
-    string(TOUPPER ${GPU_API} GPU_API_DEFINE)
+    set(GPU_API_VALUES opencl cuda)
+    set_property(CACHE GPU_API PROPERTY STRINGS ${GPU_API_VALUES})
+    validate_option(GPU_API GPU_API_VALUES)
+    string(TOUPPER ${GPU_API} GPU_API)
 
     set(GPU_PREC "mixed" CACHE STRING "LAMMPS GPU precision")
-    set_property(CACHE GPU_PREC PROPERTY STRINGS double mixed single)
-    string(TOUPPER ${GPU_PREC} GPU_PREC_DEFINE)
+    set(GPU_PREC_VALUES double mixed single)
+    set_property(CACHE GPU_PREC PROPERTY STRINGS ${GPU_PREC_VALUES})
+    validate_option(GPU_PREC GPU_PREC_VALUES)
+    string(TOUPPER ${GPU_PREC} GPU_PREC)
 
-    if(GPU_PREC_DEFINE STREQUAL "DOUBLE")
+    if(GPU_PREC STREQUAL "DOUBLE")
       set(GPU_PREC_SETTING "DOUBLE_DOUBLE")
-    elseif(GPU_PREC_DEFINE STREQUAL "MIXED")
+    elseif(GPU_PREC STREQUAL "MIXED")
       set(GPU_PREC_SETTING "SINGLE_DOUBLE")
-    elseif(GPU_PREC_DEFINE STREQUAL "SINGLE")
+    elseif(GPU_PREC STREQUAL "SINGLE")
       set(GPU_PREC_SETTING "SINGLE_SINGLE")
     endif()
 
     file(GLOB GPU_LIB_SOURCES ${LAMMPS_LIB_SOURCE_DIR}/gpu/*.cpp)
     file(MAKE_DIRECTORY ${LAMMPS_LIB_BINARY_DIR}/gpu)
 
-    if(GPU_API_DEFINE STREQUAL "CUDA")
+    if(GPU_API STREQUAL "CUDA")
       find_package(CUDA REQUIRED)
       find_program(BIN2C bin2c)
       if(NOT BIN2C)
@@ -882,11 +919,13 @@ if(PKG_GPU)
       target_include_directories(nvc_get_devices PRIVATE ${CUDA_INCLUDE_DIRS})
 
 
-    elseif(GPU_API_DEFINE STREQUAL "OPENCL")
+    elseif(GPU_API STREQUAL "OPENCL")
       find_package(OpenCL REQUIRED)
       set(OCL_TUNE "generic" CACHE STRING "OpenCL Device Tuning")
-      set_property(CACHE OCL_TUNE PROPERTY STRINGS intel fermi kepler cypress generic)
-      string(TOUPPER ${OCL_TUNE} OCL_TUNE_DEFINE)
+      set(OCL_TUNE_VALUES intel fermi kepler cypress generic)
+      set_property(CACHE OCL_TUNE PROPERTY STRINGS ${OCL_TUNE_VALUES})
+      validate_option(OCL_TUNE OCL_TUNE_VALUES)
+      string(TOUPPER ${OCL_TUNE} OCL_TUNE)
 
       include(OpenCLUtils)
       set(OCL_COMMON_HEADERS ${LAMMPS_LIB_SOURCE_DIR}/gpu/lal_preprocessor.h ${LAMMPS_LIB_SOURCE_DIR}/gpu/lal_aux_fun1.h)
@@ -908,7 +947,7 @@ if(PKG_GPU)
       add_library(gpu STATIC ${GPU_LIB_SOURCES})
       target_link_libraries(gpu ${OpenCL_LIBRARIES})
       target_include_directories(gpu PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/gpu ${OpenCL_INCLUDE_DIRS})
-      target_compile_definitions(gpu PRIVATE -D_${GPU_PREC_SETTING} -D${OCL_TUNE_DEFINE}_OCL -DMPI_GERYON -DUCL_NO_EXIT)
+      target_compile_definitions(gpu PRIVATE -D_${GPU_PREC_SETTING} -D${OCL_TUNE}_OCL -DMPI_GERYON -DUCL_NO_EXIT)
       target_compile_definitions(gpu PRIVATE -DUSE_OPENCL)
 
       list(APPEND LAMMPS_LINK_LIBS gpu)
@@ -1159,9 +1198,9 @@ if(BUILD_MPI)
 endif()
 if(PKG_GPU)
   message(STATUS "GPU Api: ${GPU_API}")
-  if(GPU_API_DEFINE STREQUAL "CUDA")
+  if(GPU_API STREQUAL "CUDA")
     message(STATUS "GPU Arch: ${GPU_ARCH}")
-  elseif(GPU_API_DEFINE STREQUAL "OPENCL")
+  elseif(GPU_API STREQUAL "OPENCL")
     message(STATUS "OCL Tune: ${OCL_TUNE}")
   endif()
   message(STATUS "GPU Precision: ${GPU_PREC}")